Version 2 (modified by todd.a, 14 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
- If the backing variable doesn't exist but there is an initial value assignment to the property or
- 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)