德尔福:2010年索引属性的RTTI? [英] Delphi: RTTI for indexed properties in 2010?

查看:133
本文介绍了德尔福:2010年索引属性的RTTI?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  TOtherClass = class(TObject)
public
FData:string;
结束

TMyClass = class(TObject)
private
FIndxPropList:TOtherClass数组;
函数GetIndxProp(Index:Integer):TOtherClass;
procedure SetIndxProp(Index:Integer; Value:TOtherClass);
public
属性IndxProp [Index:Integer]:TOtherClass读取GetIndxProp写入SetIndxProp;
结束

实现的访问说明符为

 函数TMyClass.GetIndxProp(Index:Integer):TOtherClass; 
begin
结果:= self.FIndxPropList [Index];
结束

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

它的用法可以说明如下:

  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;
结束

没关系这个设计的明显缺陷。我意识到我希望能够通过RTTI访问IndxProp属性,随后将IndxProp移动到已发布的部分。对于我的失望,我发现在发布的部分不允许编入索引的属性。据我所知(参见Barry Kellys在我如何评论使用RTTI访问Delphi数组属性),移动到D2010将不能使我这样做。



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



我的问题是:如果在D2010可以获得RTTI的公共字段是真的,不应该是我的原始示例以上)在D2010(与RTTI))工作?感谢提前!

解决方案

是的,如果所有的属性读者都是索引到数组字段或列表类字段,您可以使用RTTI直接索引到该字段。这是一种脆弱的,因为它打破了封装,要求你编写代码到一个具体的实现细节,而不是一般的原则,这是RTTI主要的好处。您的RTTI代码必须与您的类的确切结构相匹配,如果更改,则必须更改代码。但是,如果没有可用的替代方法,因为数组属性对它们没有RTTI,这可能是唯一的方法,对于现在至少。



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


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!

解决方案

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...)

这篇关于德尔福:2010年索引属性的RTTI?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆