Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Properties

A property is a pair of methods that reads and writes like a field. The caller writes t.Celsius = 21.5 and print t.Celsius, and the type runs code on each side: that is where it checks the value, converts it, or computes it from other fields.

type Thermostat
    declare property Celsius( ) as float64                '' get
    declare property Celsius( byval value as float64 )    '' set
    declare property Fahrenheit( ) as float64             '' get only
    declare property Preset( byval slot as int32 ) as float64
    declare property Preset( byval slot as int32, byval value as float64 )
  private:
    celsius_ as float64
    presets_( 1 to 3 ) as float64
end type

property Thermostat.Celsius( ) as float64
    return celsius_
end property

'' The setter is where the type keeps its own rules.
property Thermostat.Celsius( byval value as float64 )
    if value < -273.15 then value = -273.15
    celsius_ = value
end property

'' Computed on demand, so it can never disagree with Celsius.
property Thermostat.Fahrenheit( ) as float64
    return celsius_ * 9 / 5 + 32
end property

'' A property can take an index, like an array the type controls.
property Thermostat.Preset( byval slot as int32 ) as float64
    return presets_( slot )
end property

property Thermostat.Preset( byval slot as int32, byval value as float64 )
    presets_( slot ) = value
end property

dim as Thermostat t
t.Celsius = 21.5                    '' calls the setter
print "celsius"; t.Celsius; ", fahrenheit"; t.Fahrenheit

t.Celsius += 2.5                    '' get, add, then set
print "warmer:"; t.Celsius

t.Celsius = -500
print "asked for -500, got "; t.Celsius


t.Preset( 2 ) = 18
print "preset 2 is"; t.Preset( 2 )

Output

celsius 21.5, fahrenheit 70.7
warmer: 24
asked for -500, got -273.15
preset 2 is 18

A property is declared with property instead of sub or function:

  • The getter takes no value and returns one: property Celsius( ) as float64. It runs wherever the property is read.
  • The setter takes the new value and returns nothing. It runs wherever the property is assigned, and it is the place the type defends its rules: asking for -500 degrees gives absolute zero.
  • A property with only a getter is read-only. Fahrenheit is computed from celsius_ every time, so it can never disagree with it.
  • A property can take an index, as Preset( slot ) does. It then reads like an array whose elements the type controls.

A property with only a setter can be assigned but never read:

'' A property with only a setter can be assigned but never read.
type Door
    declare property Code( byval value as int32 )
  private:
    code_ as int32
end type

property Door.Code( byval value as int32 )
    code_ = value
end property

dim as Door d
d.Code = 1234
print d.Code                        '' refused: there is no getter
writeonly.tiko(14,8): error TKO0934: 'code' is a property with only a setter: it can be assigned, not read
     |
  14 | print d.Code                        '' refused: there is no getter
     |        ^

The fields behind the properties are private:, which is what makes the setter's rule hold: nothing outside the type can write celsius_ directly. Access control explains the sections.

When a property only stores a value, an auto-property writes both accessors for you, and a property block keeps a getter and setter together in one place.

Activities

  1. Add a read-write Kelvin property that stores into the same celsius_ field.
  2. Make the Preset setter ignore a slot outside 1 to 3 instead of writing past the array.