Wiki

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, It's 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       # backing variable with (implicit) protected access
pro nLife from var     # property nLife uses backing var _nLife
# above line same as 
pro nLife  from _nLife
# but can use a different backing variable name from the property name
pro numLife from _nLife

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

pro nLife0 from var # use protected or private backing variable of same name
#or alternatively property and backing variable explicitly named
pro nLife from __nLife0

You can implicitly create (a protected) initialised backing variable and property in one line like

pro nLife from var = 47  # type inferred from initial value

# or explicitly specifying type and initial value
pro nLife from var as int = 47

# More commonly perhaps a set or get variant can be given in the same manner
## (assume above prop dcls not made, any one of below is also valid)
get nLife from var
get nlifeSource from nLife

set nLife from var   # name same as backing variable
set nLifeSink from nlife  # any name same or unrelated to backing variable

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.

Within the setter code block in such a variant an implicit parameter (of the same type as the property) named value
is provided that has the value passed or assigned to the property.

var _seed = 21

# a calculated property
pro nLife 
   get
        return 70 - _seed
   set
        # implicit parameter 'value' contains the value given to set into the property 
        require value >0 and value <65
        _seed = 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> [from {var, <backingVariableName>} [as <Type>] [= <initValue>] ] 
    [has <AttributeList>] 
    [is <accessModifier>]
    [<DocString>]

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

pro <propName> [from {var, <backingVariableName>} [as <Type>] [= <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