简体   繁体   中英

How can I use a class property index to assign a variable?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM