Delphi 2010中是否支持索引属性的RTTI?

3

请原谅以下代码示例的冗长。使用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;

请忽略这个“设计”的明显缺陷。我想访问属性IndxProp的RTTI,因此将IndxProp移动到了published部分。令人失望的是,索引属性不允许在published部分中使用。据我所知(请参见Barry Kelly在How do I access Delphi Array Properties using RTTI的评论),转向D2010也不能实现这一点。
另一方面,以下是Robert Loves的博客中的一句话:“...属性和方法现在可以通过RTTI在public和published部分中使用,并且字段在所有部分中都可用。”(我斜体)。
我的问题是:如果确实可以在D2010中获取公共字段的RTTI,那么我的原始示例(如上所示)应该在D2010中(使用RTTI)工作吗?提前感谢您!
1个回答

2
是的,如果所有属性读取器只是索引到数组字段或列表类字段中,则可以使用RTTI直接索引到该字段。但这种方法比较脆弱,因为它会破坏封装性,需要您编写特定于实现细节而不是一般原则的代码,这正是RTTI主要用途所在。您的RTTI代码必须与类的确切结构匹配,如果更改了类的结构,则还必须更改代码。这有点违背使用RTTI的目的。
但是,如果没有其他可用的选择,因为数组属性没有针对它们的RTTI,那么现在可能是唯一的方法。
编辑:更新此答案。XE2中扩展的RTTI系统添加了对索引属性的支持。(然而,由于无关的稳定性问题,您可能需要等待XE3...)

更新:Delphi XE2引入了TRttiIndexedProperty,它提供了获取索引属性的运行时类型信息的功能。 - menjaraz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接