Class 为给定的自定义属性扫描所有类
我正在寻找一种方法,可以在不使用RegisterClass()的情况下扫描所有加载的类,查找包含自定义属性的类。首先,您必须创建Class 为给定的自定义属性扫描所有类,class,delphi,attributes,delphi-xe,Class,Delphi,Attributes,Delphi Xe,我正在寻找一种方法,可以在不使用RegisterClass()的情况下扫描所有加载的类,查找包含自定义属性的类。首先,您必须创建TRttiContext,然后使用getTypes获取所有加载的类。之后,您可以通过TypeKind=tkClass过滤类型; 下一步是枚举属性并检查它是否具有您的属性 属性和测试类增量: unit Unit3; interface type TMyAttribute = class(TCustomAttribute) end; [TMyAt
TRttiContext
,然后使用getTypes
获取所有加载的类。之后,您可以通过TypeKind=tkClass
过滤类型;
下一步是枚举属性并检查它是否具有您的属性
属性和测试类增量:
unit Unit3;
interface
type
TMyAttribute = class(TCustomAttribute)
end;
[TMyAttribute]
TTest = class(TObject)
end;
implementation
initialization
TTest.Create().Free(); //if class is not actually used it will not be compiled
end.
然后找到它:
program Project3;
{$APPTYPE CONSOLE}
uses
SysUtils, rtti, typinfo, unit3;
type TMyAttribute = class(TCustomAttribute)
end;
var ctx : TRttiContext;
t : TRttiType;
attr : TCustomAttribute;
begin
ctx := TRttiContext.Create();
try
for t in ctx.GetTypes() do begin
if t.TypeKind <> tkClass then continue;
for attr in t.GetAttributes() do begin
if attr is TMyAttribute then begin
writeln(t.QualifiedName);
break;
end;
end;
end;
finally
ctx.Free();
readln;
end;
end.
程序项目3;
{$APPTYPE控制台}
使用
SysUtils、rtti、typinfo、unit3;
类型TMyAttribute=class(TCustomAttribute)
结束;
var-ctx:TRttiContext;
t:trtti型;
属性:TCustomAttribute;
开始
ctx:=TRttiContext.Create();
尝试
对于ctx.GetTypes()中的t
如果是t.TypeKind tkClass,则继续;
对于t.GetAttributes()中的attr,请执行begin
如果attr是TMyAttribute,则开始
writeln(t.QualifiedName);
打破
结束;
结束;
结束;
最后
ctx.Free();
readln;
结束;
结束。
输出为单元3。t测试
调用RegisterClass向流媒体系统注册一个类。。。。注册类后,组件流系统即可加载或保存这些类
因此,如果您不需要组件流(只需查找具有某些属性的类),则无需注册类
,您可以使用RTTI单元公开的新RTTI功能
var
context: TRttiContext;
typ: TRttiType;
attr: TCustomAttribute;
method: TRttiMethod;
prop: TRttiProperty;
field: TRttiField;
begin
for typ in context.GetTypes do begin
for attr in typ.GetAttributes do begin
Writeln(attr.ToString);
end;
for method in typ.GetMethods do begin
for attr in method.GetAttributes do begin
Writeln(attr.ToString);
end;
end;
for prop in typ.GetProperties do begin
for attr in prop.GetAttributes do begin
Writeln(attr.ToString);
end;
end;
for field in typ.GetFields do begin
for attr in field.GetAttributes do begin
Writeln(attr.ToString);
end;
end;
end;
end;
此代码枚举与方法、属性和字段以及类型关联的属性。当然,您需要做的不仅仅是Writeln(attr.ToString)
,但这应该会让您了解如何继续。您可以用常规方法测试特定属性
if attr is TMyAttribute then
....
值得一提的是,行ctx:=TRttiContext.Create()代码>根本不需要。你可以愉快地删除它!您的示例代码不完整。提供要用TMyAttribute注释的类。@menjaraz不,这不是必需的。这就是答案。@menjaraz Done:)@DavidHeffernan在这种情况下不需要Create
,但如果我使用ctx几次,就不需要保存旧的上下文数据,所以我更喜欢Create
始终保存它(:@teran无论发生什么,它都是按需创建的,因此如果你想清除旧的,那么在完成后调用Free
。我个人发现这种风格(如Embarcadero所示)让记录看起来像类是一种误导。我希望他们不要在记录中使用Create
和Free
,因为它使代码的读取器知道ctx
是一种堆分配的引用类型。它绝不是。