Delphi 为继承的属性创建属性
[编辑]我正试图让RTTI识别TList泛型类的“Items”属性,以便对其应用属性。我已经编写了一个控制台应用程序,在这里输出RTTI属性:Delphi 为继承的属性创建属性,delphi,inheritance,attributes,delphi-2010,Delphi,Inheritance,Attributes,Delphi 2010,[编辑]我正试图让RTTI识别TList泛型类的“Items”属性,以便对其应用属性。我已经编写了一个控制台应用程序,在这里输出RTTI属性: program RTTIAttributes; {$APPTYPE CONSOLE} uses Classes, Generics.Collections, RTTI, SysUtils; type TDataMember = class(TCustomAttribute); TCustomer = class pr
program RTTIAttributes;
{$APPTYPE CONSOLE}
uses
Classes,
Generics.Collections,
RTTI,
SysUtils;
type
TDataMember = class(TCustomAttribute);
TCustomer = class
private
FName: string;
public
[TDataMember]
property Name: string read FName write FName; // <- attribute IS recognised by RTTI
end;
{ inheritance tree: TList<T> -> TObjectList<T> -> TCustomerList
Here are the base properties declared in TList<T>
TList<T> = class(TEnumerable<T>)
...
public
property Capacity: Integer read GetCapacity write SetCapacity;
property Count: Integer read FCount write SetCount;
property Items[Index: Integer]: T read GetItem write SetItem; default; <- not recognised as RTTI property...!
property OnNotify: TCollectionNotifyEvent<T> read FOnNotify write FOnNotify;
end;
}
TCustomerList = class(TObjectList<TCustomer>)
public
//[TDataMember]
property Items; // <- inherited property, but NOT recognised by RTTI & hence cannot inspect attributes
end;
procedure DoRTTIObject(AObject: TObject);
var
LContext: TRttiContext;
LProp: TRttiProperty;
LAttr: TCustomAttribute;
begin
LContext := TRttiContext.Create;
try
Writeln('Process Class: ' + AObject.ClassName);
for LProp in LContext.GetType(AObject.ClassType).GetProperties do
begin
Writeln('Found Property: ' + AObject.ClassName + '.' + LProp.Name);
for LAttr in LProp.GetAttributes do
if LAttr is TDataMember then
Writeln(AObject.ClassName + '.' + LProp.Name + ': HAS TDataMember attribute')
else
Writeln(AObject.ClassName + '.' + LProp.Name + ': DOES NOT HAVE TDataMember attribute');
end;
Writeln('');
finally
LContext.Free;
end;
end;
var
LList: TCustomerList;
begin
LList := TCustomerList.Create;
LList.Add(TCustomer.Create);
DoRTTIObject(LList);
DoRTTIObject(LList[0]);
Readln;
end.
因此,无论出于何种原因,我无法确定,RTTI识别祖先类声明的属性中的3个,而不是4个
有什么想法吗?什么德尔福版本?将可见性从受保护更改为公共可能还不够。也许您应该将它推广到已发布的版本,并使用经典(非扩展)RTTI.delphi2010。继承的属性(项)已在祖先类中公开。我只是尝试重新声明它并引入一个属性。将其设置为“已发布”无效,会出现错误:E2188已发布属性“Items”不能为数组类型。还有其他想法吗?哦,这是一种数组类型,你想在它上面使用扩展RTTI吗?我建议您放弃x阵列,使用集合。如果您不熟悉
TCollectionItem
,那么这是嵌入大量灵活对象并为其提供经典标准rtti的经典rtti方法。因为它是类类型,所以属性可以工作。我从TObjectList开始下降,所以我认为它使用了TEnumerable。我不想更改项目的基本类型,我只想能够向属性添加一个属性,我可以使用RTTI检测到该属性。我认为遗漏所有这些信息会使您的问题难以回答。也许可以发布一个显示此问题的类型的最小完整示例,而不是上面的非类型化代码。TCustomerList是TObjectList这一事实与属性项无关,它的类型是什么?
Process Class: TCustomerList
Found Property: TCustomerList.OwnsObjects
Found Property: TCustomerList.Capacity
Found Property: TCustomerList.Count
Found Property: TCustomerList.OnNotify
Process Class: TCustomer
Found Property: TCustomer.Name
TCustomer.Name: HAS TDataMember attribute