Delphi:2010 年索引属性的 RTTI?

发布于 2024-08-26 01:47:08 字数 1940 浏览 2 评论 0原文

请原谅以下代码示例的冗长。使用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 移至已发布部分。令我非常失望的是,我发现已发布部分不允许使用索引属性。据我了解(请参阅巴里·凯利的评论 我该如何使用 RTTI 访问 Delphi 数组属性),迁移到 D2010 无法让我执行此操作。

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

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

Please forgive the verbosity of the following code example. Using Delphi 2009, I created the two classes TOtherClass and 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;

with access specifiers implemented as

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;

It's use can be illustrated as follows:

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;

Never mind the obvious flaws of this "design". I realized that I'd like to be able to access the property IndxProp via RTTI, and subsequently moved the IndxProp to the published section. Much to my disappointment, I found that indexed properties are not allowed in the published section. As far as I understand (see Barry Kellys comment at How do I access Delphi Array Properties using RTTI), moving to D2010 won't enable me to do this.

On the other hand, the following is a quote from Robert Loves blog: "... properties and methods are now available via RTTI in both public and published sections, and Fields are available in all of the sections." (My italics.)

My question is this: if it's true that it is possible to get RTTI for public fields in D2010, shouldn't my original example (as shown above) work in D2010 (with RTTI)? Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

爱冒险 2024-09-02 01:47:08

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

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

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

Yes, if all the property reader does is index into an array field or list-class field, then you can use RTTI to index into the field directly. This is kind of fragile, though, since it breaks your encapsulation, requiring you to write code to a specific implementation detail instead of a general principle, which is what RTTI is mainly good for. Your RTTI code has to match the exact structure of your class, and if it changes you have to change the code as well. That sort of defeats the purpose of using RTTI.

But, if there's no alternative available, since array properties have no RTTI for them, it may be the only way, for now at least.

EDIT: Updating this answer. Support for indexed properties was added to the extended RTTI system in XE2. (However, due to unrelated stability issues, you might want to wait for XE3...)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文