Author: Max Kleiner
In an interface we can't use fields so when you declare a class that implements one
or more interfaces, you must provide an implementation of all the methods declared
in the interface and the fields too. Therefore Array Properties are welcome.
Answer:
Properties come in two mode behaviour, scalar and array. An array property can't be
published in component design, but they have many other uses to struct your class.
One of the best features is the array index can be ANY type, and multidimensional
arrays are possible, too. For array-type properties, we must use getter and setter,
means read and write methods; no possibilitie to map an array-type property
directly to an array-type field. Thats real design. First we need a class or
interface:
1 IChaosBase = interface(IUnknown)
2 ['{C6661345-26D1-D611-9FAD-C52B9EAAF7C0}']
3 function getScales(index: integer): Tdouble; stdcall;
4 procedure setScales(index: integer; scale: Tdouble); stdcall;
5 property scales[index: integer]: TDouble
6 read getScales write setScales;
7 end;
8
9 //The aim is to store those 4 fields with the property scales[]:
10
11 scaleX1: double;
12 scaleX2: double;
13 scaleY1: double;
14 scaleY2: double;
Second we need the implementing class. The simplest way to implement the _AddRef,
_Release, and QueryInterface methods is to inherit them from TInterfacedObject,
thats the meaning of TInterfacedObject:
15 type
16 TDouble = double;
17 TDoubleArray = array[1..4] of TDouble;
18
19 TChaosBase = class(TInterfacedObject, IChaosBase)
20 protected
21 myscales: TDoubleArray;
22 function getScales(index: integer): TDouble; stdcall;
23 procedure setScales(index: integer; scale: TDouble); stdcall;
24 property scales[index: integer]: TDouble
25 read getScales write setScales;
26 end;
Now comes the setter and getter, especially the setter setScalses() needs a second
parameter to define the type (you remember the array index can be ANY type) in our
case a simple double. Also the datastructure can be choosen (list, map,
collection), in our case the structure is a simple array.
27
28 function TChaosBase.getScales(index: integer): Tdouble;
29 begin
30 result := myscales[index];
31 end;
32
33 procedure TChaosBase.setScales(index: integer; scale: Tdouble);
34 begin
35 myScales[index] := scale;
36 end;
37
38 //At least the write-access goes like this from any class or method:
39
40 scales[1] := 0.89;
41 scales[2] := 1.23;
42 scales[3] := 0.23;
43 scales[4] := 1.34;
44
45 //or the read-access is a simple call to the propertie:
46
47 scaledX := (X - scales[1]) / (scales[2] - scales[1]);
48 scaledY := (Y - scales[4]) / (scales[3] - scales[4]);
Default access: There can be only one default array property for each class, means
instead of myChaosBase.scales[i] we can use myChaosBase[i] with the directive
default:
property scales[index: integer]: TDouble read getScales write setScales; default;
|