扫描给定自定义属性的所有类

时间:2012-02-29 08:44:36

标签: class delphi attributes delphi-xe

我正在寻找一种方法来扫描包含自定义属性的类的所有已加载类,如果可能的话,不使用RegisterClass()。

2 个答案:

答案 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
  ....