Class 如何使用类属性索引分配变量?

Class 如何使用类属性索引分配变量?,class,delphi,properties,Class,Delphi,Properties,我创建了一个类: type TShape = class private FHeight: Integer; FWidth: Integer; FDepth: Integer; public constructor CreateShape(AHeight: Integer; AWidth: Integer; ADepth: Integer); property height:

我创建了一个类:

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;

目前,我通过使用属性名称分配变量来分配值:

cube := TShape.CreateShape(5, 5, 5);

height1 := cube.FHeight;
width1 := cube.FWidth;
depth1 := cube.FDepth;

但是我如何使用索引而不是名称来分配属性,因此height1:=cube.FHeight将改为height1:=cube[0]?

我想您误解了它的工作原理。它们允许您对多个属性使用单个getter或setter函数:

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;
因此,它只能与getter和setter函数一起使用;不能使用字段

你似乎对一些不同的东西感兴趣,这是一个默认值。数组属性是对象用户的数组属性,如Memo1.Lines[4]。因此,它是一个数组的单一属性

在您的情况下,可以添加公共属性

property Dimensions[Index: Integer]: Integer read GetDimension;
私有getter函数在哪里

function GetDimension(Index: Integer): Integer;
定义为

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;
这将仍然使用FHHEIGHT、FWidth和FDepth字段来存储引擎盖下的数据

或者,您可以将数据存储在静态或动态整数数组中。然后可以创建索引属性宽度、高度和深度,并使用与数组属性相同的getter函数:

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;
现在您可以访问MyShape.Height、MyShape.Width和MyShape.Depth,以及MyShape.Dimensions[0]、MyShape.Dimensions[1]和MyShape.Dimensions[2]

如果将数组属性标记为默认值

您还可以编写MyShape[0]、MyShape[1]和MyShape[2]


注意:为了简单起见,我上面的示例只使用getter。但是二传也能起作用。

我想你误解了它的工作原理。它们允许您对多个属性使用单个getter或setter函数:

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;
因此,它只能与getter和setter函数一起使用;不能使用字段

你似乎对一些不同的东西感兴趣,这是一个默认值。数组属性是对象用户的数组属性,如Memo1.Lines[4]。因此,它是一个数组的单一属性

在您的情况下,可以添加公共属性

property Dimensions[Index: Integer]: Integer read GetDimension;
私有getter函数在哪里

function GetDimension(Index: Integer): Integer;
定义为

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;
这将仍然使用FHHEIGHT、FWidth和FDepth字段来存储引擎盖下的数据

或者,您可以将数据存储在静态或动态整数数组中。然后可以创建索引属性宽度、高度和深度,并使用与数组属性相同的getter函数:

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;
现在您可以访问MyShape.Height、MyShape.Width和MyShape.Depth,以及MyShape.Dimensions[0]、MyShape.Dimensions[1]和MyShape.Dimensions[2]

如果将数组属性标记为默认值

您还可以编写MyShape[0]、MyShape[1]和MyShape[2]


注意:为了简单起见,我上面的示例只使用getter。但是setter也可以工作。

注意,在最后一个代码块中,您编写了height1:=cube.FHeight;但可能应该写入height1:=cube.Height;。您希望使用公共属性,而不是私有字段。私有字段只能从类natural内部以及与不太自然的类相同的单元中访问;但可能应该写入height1:=cube.Height;。您希望使用公共属性,而不是私有字段。只能从类natural内部以及与类natural稍差的同一单元内访问private字段。