I have created a class:
type
TShape = class
private
FHeight: Integer;
FWidth: Integer;
FDepth: Integer;
public
constructor CreateShape(AHeight: Integer; AWidth: Integer; ADepth: Integer);
property height: Integer index 0 read FHeight write FHeight;
property width: Integer index 1 read FWidth write FWidth;
property depth: Integer index 2 read FDepth write FDepth;
end;
.
constructor TShape.CreateShape(AHeight: Integer; AWidth: Integer;
ADepth: Integer);
begin
inherited Create;
FHeight := AHeight;
FWidth := AWidth;
FDepth := ADepth;
end;
And currently I assign the values by using the name of the property to assign a variable:
cube := TShape.CreateShape(5, 5, 5);
height1 := cube.FHeight;
width1 := cube.FWidth;
depth1 := cube.FDepth;
But how do I use the index instead of the name to assign a property, so height1:= cube.FHeight
would instead be height1:= cube[0]
?
I think you have misunderstood how index
specifiers work. They allow you to use a single getter or setter function for several properties:
TTest = class
private
function GetColor(AIndex: Integer): TColor;
public
property BackgroundColor: TColor index 0 read GetColor;
property ForegroundColor: TColor index 1 read GetColor;
end;
// ...
function TTest.GetColor(AIndex: Integer): TColor;
begin
case AIndex of
0:
Result := clRed; // background colour
1:
Result := clBlue; // foreground colour
else
Result := clBlack;
end;
end;
Hence, it can only be used with getter and setter functions; you cannot use fields.
You seem to be interested in something different, an array property , which is in addition default
. An array property is a property that is an array to the object's user (like Memo1.Lines[4]
). Hence, it is a single property which is an array.
In your case, you could add a public property
property Dimensions[Index: Integer]: Integer read GetDimension;
where the private getter function
function GetDimension(Index: Integer): Integer;
is defined as
function TShape.GetDimension(Index: Integer): Integer;
begin
case Index of
0:
Result := FHeight;
1:
Result := FWidth;
2:
Result := FDepth;
else
Result := 0; // or raise an exception
end;
end;
This would still use your FHeight
, FWidth
, and FDepth
fields to store the data under the hood.
Alternatively, you could store the data in a static or dynamic array of integers. Then you could create indexed properties Width
, Height
, and Depth
and use the same getter function as for the array property:
type
TShape = class
private
FDimensions: array[0..2] of Integer;
function GetDimension(Index: Integer): Integer;
public
constructor CreateShape(AHeight: Integer; AWidth: Integer; ADepth: Integer);
property Height: Integer index 0 read GetDimension;
property Width: Integer index 1 read GetDimension;
property Depth: Integer index 2 read GetDimension;
property Dimensions[Index: Integer]: Integer read GetDimension;
end;
// ...
{ TShape }
constructor TShape.CreateShape(AHeight, AWidth, ADepth: Integer);
begin
FDimensions[0] := AHeight;
FDimensions[1] := AWidth;
FDimensions[2] := ADepth;
end;
function TShape.GetDimension(Index: Integer): Integer;
begin
if InRange(Index, Low(FDimensions), High(FDimensions)) then
Result := FDimensions[Index]
else
raise Exception.CreateFmt('Invalid dimension index: %d', [Index]);
end;
Now you can access MyShape.Height
, MyShape.Width
, and MyShape.Depth
, as well as MyShape.Dimensions[0]
, MyShape.Dimensions[1]
, and MyShape.Dimensions[2]
.
If you mark the array property as default
,
property Dimensions[Index: Integer]: Integer read GetDimension; default;
you can also write MyShape[0]
, MyShape[1]
, and MyShape[2]
.
Note: For simplicity, my examples above only use getters. But setters work as well.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.