Delphi:2010 年索引属性的 RTTI?

标签 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 Kelly 在 How do I access Delphi Array Properties using RTTI 的评论),迁移到 D2010 并不能让我做到这一点。

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

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

最佳答案

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

但是,如果没有可用的替代方案,因为数组属性没有 RTTI,那么它可能是唯一的方法,至少目前是这样。

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

关于Delphi:2010 年索引属性的 RTTI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2491308/

相关文章:

delphi - 使用自定义样式时从未调用过表单销毁(OnDestroy)? XE7

delphi - 如何将 "of object"程序分配给 "reference to"程序?

android - Delphi Android RESTRequest: channel 无法恢复,将被丢弃

arrays - 可以连接字符串常量数组吗?

delphi - 为什么这个 PAnsiChar 在转换为 AnsiString 时会被截断?

delphi - IdHTTP 基本身份验证访问冲突

c++ - 为什么在 C++ 中运行时才知道动态类型?

delphi - 在Delphi中获取接口(interface)引用的GUID

html - Delphi 中是否有一些功能可以将带有 html 命名和编号实体的字符串转换为 unicode 文本?

C++ RTTI 继承导致类大小增加