Wiki
Version 1 (modified by hopscc, 15 years ago)

--

Properties

Properties are members that are used as if they are public data members, but are actually implemented via special methods called accessors.
They are accessed using the same syntax as fields but do not designate storage locations.
Instead, properties have accessors that read, write, or compute their values.
Values can be reflected directly (or indirectly (filtered)) in or out of a backing variable or computed, Its entirely up to the accessor.

There are 3 keywords for defining a property:
get defines a readOnly property ( Can access its value but cant change it).
set defines a writeOnly property ( Can write a new value but cant read it).
pro defines a property that is both readable and writable.

Most commonly a property accessor uses a backing variable (field) which the accessor just reflects.
There is a special form to simplify this using a clause beginning with keyword from.

  • from var
    If the word following from is var the property will get or set its value unchanged
    from a backing variable named the same as the property name with a single underscore prepended to it.
    • If the backing variable doesn't exist but there is an initial value assignment to the property or
      a type declaration on the property, the backing variable will be implicitly created for you
  • from <backingVarId>
    Otherwise the word following the from must be the name of an existing backing store variable.
var _nLife  = 47       # protected access
pro nLife from var     # property nLife uses backing var _nLife
# above same as 
pro nLife  from _nLife
# but can use a different backing variable name from property name
pro numLife from _nLife

# or use a backing variable with different (shortcutted) accessability
var __nLife0 = 48   # private access

pro nLife from __nLife

Can implicitly create initialised backing variable and property in one line like

pro nLife = 47

Finally if an accessor needs to translate, filter or modify in some way a backing variable or provide a virtual variable (computed)
there is a longer syntax variant where either of both the get and set accessors can be specified with a block of code to
store (setter) or generate (getter) the property value.

Properties can have Attributes and the default access modifiers? can be overridden explicitly if desired.

DocStrings describing the property are both allowed and encouraged.

There is a special type of property called an Indexor which allows an instance to be accessed
using an array offset like syntax e.g. coll[x] .
Usually this is implemented for classes that act as containers, for access to the contained items.
The syntax for indexors is as described above except that the property name is [] with indexes comma
separated (if multiple) between the [] and the accessors must be coded explicitly ( the from clause shorthand is not available).

Grammar

get <propName> [as <Type>] [from {var, <backingVariableName>} [= <initValue>] ] 
    [has <AttributeList>] 
    [is <accessModifier>]
    [<DocString>]

set <propName> [as <Type>] [from {var, <backingVariableName>} [= <initValue>] ] 
    [has <AttributeList>] 
    [is <accessModifier>]
    [<DocString>]

pro <propName> [as <Type>] [from {var, <backingVariableName>} [= <initValue>]] 
    [has <AttributeList>] 
    [is <accessModifier>]
    [<DocString>]

# full accessor variant 
pro <propName> 
    [has <AttributeList>] 
    [is <accessModifier>]
    [<DocString>]

    get 
        [...]
        return <value>
    set
        [...] # assign or otherwise do something with implicit arg "value" (passed in) 

#Indexors

{pro,set,get} '[' <indexer expression> ']' [as <Type>]    
    [has <AttributeList>] 
    [is <accessModifier>]
    [<DocString>]
    [
    get 
        [...]
        return <value>
    set
        [...] # assign or otherwise do something with implicit arg "value" (passed in) 

Examples

class TimePeriod
    var seconds as float32 is private 

    pro hours as float32
        get 
	    return .seconds / 3600 
	set 
            .seconds = value * 3600 

class Program
    def main is shared
        t = TimePeriod()

        # Assigning the hours property causes the 'set' accessor to be called.
        t.hours = 24

        # Evaluating the hours property causes the 'get' accessor to be called.
        print "Time in hours: ",  t.hours
class Employee
    var numberOfEmployees as int = 0
        is shared
    var __counter as int = 0
        is shared
    var _name = ''

    # A read-write instance property:
    pro name from var

    # A read-only static property:
    get counter from __counter is shared

    # Constructor:
    cue init
        base.init
        # Calculate the employee's number:
        __counter = .counter + 1 + .numberOfEmployees

class MainClass
    def main is shared
        Employee.numberOfEmployees = 100
        e1 = Employee()
        e1.name = "Claude Vige"
        print String.format("Employee number: {0}", Employee.counter)
        print String.format("Employee name: {0}", e1.name)
# Output is
#Employee number: 101
#Employee name: Claude Vige

Indexor example

class IdxColl
    var _coll = []

    cue init
        base.init
        _coll = [1,2,3,'xx']

    pro [idx as int] as Object
        get
            return _coll[idx]
        set
            _coll[idx] = value

    def main is shared
        c = ProColl()
        assert c[0] == 1
        assert c[3] == 'xx'
        c[2] = 'yy'
        assert c[2] == 'yy'

Notes

See Also

 Properties(C# Programming Reference)

 Properties(C# Programming Guide)

Back to LanguageTopics