我正在寻找一种方法来扫描包含自定义属性的类的所有已加载类,如果可能的话,不使用RegisterClass()。
答案 0 :(得分:7)
首先,您必须创建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.
输出为Unit3.TTest
调用RegisterClass向流系统注册一个类....一旦注册了类,它们就可以被组件流系统加载或保存。
因此,如果您不需要组件流(只需查找具有某些属性的类),则无需RegisterClass
答案 1 :(得分:4)
您可以使用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
....