= Properties = Properties are members that are used as if they are public data members, but are actually implemented via special methods called accessors.[[BR]] They are accessed using the same syntax as fields but do not designate storage locations.[[BR]] Instead, properties have accessors that read, write, or compute their values.[[BR]] 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:[[BR]] '''get''' defines a readOnly property ( Can access its value but cant change it). [[BR]] '''set''' defines a writeOnly property ( Can write a new value but cant read it).[[BR]] '''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.[[BR]] There is a special form to simplify this using a clause beginning with keyword '''from'''. * '''from var''' [[BR]] If the word following '''from''' is '''var''' the property will get or set its value unchanged [[BR]] 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 [[BR]] a type declaration on the property, the backing variable will be implicitly created for you * '''from '''[[BR]] Otherwise the word following the '''from''' must be the name of an existing backing store variable. {{{ #!cobra 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 __nLife0 }}} Can implicitly create (a protected) initialised backing variable and property in one line like {{{ #!cobra pro nLife from var = 47 # type inferred from initial value # or explicitly specifying type and initial value pro nLife from var as int = 47 }}} Finally if an accessor needs to translate, filter or modify in some way a backing variable or provide a virtual variable (computed)[[BR]] there is a longer syntax variant where either of both the '''get''' and '''set''' accessors can be specified with a block of code to[[BR]] store (setter) or generate (getter) the property value. {{{ #!cobra var _seed = 21 # a calculated property pro nLife get return 70 - _seed set require value >0 and value <65 _seed = value }}} Properties can have Attributes and the default [wiki:accessModifiers 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[[BR]] using an array offset like syntax {{{ e.g. coll[x] }}}. [[BR]] Usually this is implemented for classes that act as containers, for access to the contained items.[[BR]] The syntax for indexors is as described above except that the property name is '''[]''' with indexes comma [[BR]] separated (if multiple) between the [] and the accessors must be coded explicitly ( the '''from''' clause shorthand is not available). == Grammar == {{{ get [from {var, } [as ] [= ] ] [has ] [is ] [] set [from {var, } [as ] [= ] ] [has ] [is ] [] pro [from {var, } [as ] [= ]] [has ] [is ] [] # full accessor variant pro [has ] [is ] [] get [...] return set [...] # assign or otherwise do something with implicit arg "value" (passed in) #Indexors {pro,set,get} '[' ']' [as ] [has ] [is ] [] [ get [...] return set [...] # assign or otherwise do something with implicit arg "value" (passed in) }}} == Examples == {{{ #!cobra 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 }}} {{{ #!cobra 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 {{{ #!cobra 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 == [http://msdn.microsoft.com/en-us/library/w86s7x04%28VS.71%29.aspx Properties(C# Programming Reference)] [http://msdn.microsoft.com/en-us/library/x9fsa0sw.aspx Properties(C# Programming Guide)] [wiki:LanguageTopics Back to LanguageTopics]