德尔福:2010年RTTI的索引属性?

时间:2010-03-22 10:13:22

标签: delphi delphi-2010 rtti

请原谅以下代码示例的详细程度。使用Delphi 2009,我创建了两个类TOtherClass和TMyClass:

TOtherClass = class(TObject)
public
    FData: string;
end;

TMyClass = class(TObject)
private
    FIndxPropList: Array of TOtherClass;
    function GetIndxProp(Index: Integer): TOtherClass;
    procedure SetIndxProp(Index: Integer; Value: TOtherClass);
public
    property IndxProp[Index: Integer]: TOtherClass read GetIndxProp write SetIndxProp;
end;

将访问说明符实现为

function TMyClass.GetIndxProp(Index: Integer): TOtherClass;
begin
    Result := self.FIndxPropList[Index];
end;

procedure TMyClass.SetIndxProp(Index: Integer; Value: TOtherClass);
begin
    SetLength(self.FIndxPropList, Length(self.FIndxPropList) + 1);
    self.FIndxPropList[Length(self.FIndxPropList) - 1] := Value;
end;

它的用法可以说明如下:

procedure Test();
var
    MyClass: TMyClass;
begin
    MyClass := TMyClass.Create;
    MyClass.IndxProp[0] := TOtherClass.Create;
    MyClass.IndxProp[0].FData := 'First instance.';
    MyClass.IndxProp[1] := TOtherClass.Create;
    MyClass.IndxProp[1].FData := 'Second instance.';
    MessageDlg(MyClass.IndxProp[0].FData, mtInformation, [mbOk], 0);
    MessageDlg(MyClass.IndxProp[1].FData, mtInformation, [mbOk], 0);
    MyClass.IndxProp[0].Free;
    MyClass.IndxProp[1].Free;
    MyClass.Free;
end;

别介意这种“设计”的明显缺陷。我意识到我希望能够通过RTTI访问属性IndxProp,然后将IndxProp移动到已发布的部分。令我失望的是,我发现在已发布的部分中不允许使用索引属性。据我了解(见Barry Kellys在How do I access Delphi Array Properties using RTTI的评论),转到D2010将无法​​让我这样做。

另一方面,以下是来自Robert Loves blog的引用:“...现在可以通过RTTI在公共部分和已发布部分中使用属性和方法,并且所有的字段都可用部分“。 (我的斜体。)

我的问题是:如果确实可以在D2010中获取公共字段的RTTI,那么我的原始示例(如上所示)不应该在D2010中工作(使用RTTI)吗?提前谢谢!

1 个答案:

答案 0 :(得分:2)

是的,如果所有属性读取器都是索引到数组字段或列表类字段,那么您可以使用RTTI直接索引到该字段。但这有点脆弱,因为它打破了你的封装,要求你把代码编写到特定的实现细节而不是一般原则,这是RTTI主要适合的。您的RTTI代码必须与您的类的确切结构相匹配,如果它发生更改,您还必须更改代码。这种做法违背了使用RTTI的目的。

但是,如果没有其他选择,因为数组属性没有RTTI,所以它可能是唯一的方法,至少现在。

编辑:更新此答案。对索引属性的支持已添加到XE2中的扩展RTTI系统中。 (但是,由于无关的稳定性问题,您可能需要等待XE3 ...)