Auto-properties and property blocks
Most properties only store a value. An auto-property says so in one line: the declaration ends in its accessors, and the compiler writes both of them over a hidden field.
type Person
declare property Name as ustring get, set '' read and written like a field
declare property Age as int32 = 18 get, private set '' anyone reads, only Person writes
declare property Id as int32 get, init '' set once, by the constructor
declare constructor( byval newId as int32 )
declare sub Birthday( )
end type
constructor Person( byval newId as int32 )
Id = newId
end constructor
sub Person.Birthday( )
Age += 1
end sub
dim as Person p = Person( 42 )
p.Name = "Ann"
p.Birthday( )
print p.Name; ", age"; p.Age; ", id"; p.Id
Output
Ann, age 19, id 42
get, setreads and writes like a plain field.get, private setcan be read anywhere but written only by the type's own code, asBirthdaydoes. The setter may be less visible than the getter, never more.get, init(orgetalone) can be read anywhere and assigned only by a constructor.= 18gives the hidden field its first value.
Writing a private setter from outside is refused:
type Person
declare property Age as int32 = 18 get, private set
end type
dim as Person p
p.Age = 30 '' refused: the setter is private
autopropserror.tiko(6,2): error TKO0625: 'age' is not accessible here
An auto-property has no code of its own. When the setter has a rule to keep, write an ordinary property over a field of your own.
Property blocks
A property block defines the getter and setter together, between property
and end property. The type declares them as usual.
type Thermostat
declare property Celsius( ) as float64
declare property Celsius( byval value as float64 )
declare property Fahrenheit( ) as float64
private:
celsius_ as float64
end type
'' Both accessors in one block. In set, value is what was assigned;
'' in get, value is what will be returned.
property Thermostat.Celsius as float64
get
value = celsius_
end get
set
if value < -273.15 then value = -273.15
celsius_ = value
end set
end property
property Thermostat.Fahrenheit as float64
get
return celsius_ * 9 / 5 + 32
end get
end property
dim as Thermostat t
t.Celsius = 21.5
t.Celsius += 2.5 '' get, add, set
print "celsius"; t.Celsius; ", fahrenheit"; t.Fahrenheit
t.Celsius = -500
print "asked for -500, got "; t.Celsius
Output
celsius 24, fahrenheit 75.2
asked for -500, got -273.15
Inside both sections value is the value crossing the boundary:
- In
set, it is the value being assigned. It can be changed before it is stored, as the absolute-zero check does. - In
get, it is the result. It starts at the type's default, and whatever it holds atend getis returned.returnworks too.
Either section can be left out: Fahrenheit has only a get. get and set
open a section only when they stand alone on their line.
Static, indexed and namespace properties
type Grid
declare property Cell( byval r as int32, byval c as int32 ) as int32
declare property Cell( byval r as int32, byval c as int32, byval value as int32 )
declare static property Created as int32 get, private set
declare constructor( )
private:
cells_( 0 to 2, 0 to 2 ) as int32
end type
constructor Grid( )
Created += 1 '' one count for the whole type
end constructor
property Grid.Cell( byval r as int32, byval c as int32 ) as int32
return cells_( r, c )
end property
property Grid.Cell( byval r as int32, byval c as int32, byval value as int32 )
cells_( r, c ) = value
end property
namespace Settings
dim shared as int32 level_
declare property Level( ) as int32
declare property Level( byval value as int32 )
end namespace
property Settings.Level( ) as int32
return level_
end property
property Settings.Level( byval value as int32 )
level_ = iif( value > 10, 10, value )
end property
sub Bump( byref n as int32 )
n += 5
end sub
dim as Grid a, b
a.Cell( 1, 2 ) = 7
Bump( a.Cell( 1, 2 ) ) '' written back through the setter
print "cell"; a.Cell( 1, 2 ); ", grids"; Grid.Created
Settings.Level = 50
print "level"; Settings.Level
Output
cell 12, grids 2
level 10
- A property can take any number of indices. The setter's value comes last.
- A
staticproperty belongs to the type, not to an object:Grid.Created. It can be an auto-property too. - A property can live in a namespace, with no object at all.
- A property passed to a
byrefparameter is written back through its setter when the call returns, soBumpchanges the cell. - Compound assignment (
+=,&=, ...) andswapcall the getter and then the setter.
Activities
- Give
PersonanEmailauto-property that onlyPersonmay change, and aSetEmailmethod that refuses a value with no@. - Turn
Settings.Levelinto a property block overlevel_.