如何使用 RTTI 检索类的正确构造函数?

问题描述 投票:0回答:1

我正在使用 Delphi 中的一个类,定义如下:

type
  TMyObject = class(TObject)
    constructor Create(a: string); overload; virtual;
    constructor Create(b: integer); overload; virtual;
  end;

我需要使用 RTTI 检索

TMyObject
的构造函数列表。我尝试使用
GetMethods('Create')
实例的
TRttiType
函数来实现
TMyObject
:

var
  Context: TRttiContext;
  RttiType: TRttiType;
  Method: TRttiMethod;
begin
  Context := TRttiContext.Create;
  RttiType := Context.GetType(TMyObject);
  for Method in RttiType.GetMethods('Create') do
  begin
    // Process method
  end;

但是,我发现

GetMethods('Create')
还返回从
TObject
继承的 Create 方法,由于 TMyObject 构造函数中的附加参数,该方法不适合创建
TMyObject
实例。

如何使用 RTTI 只获取可用于创建

TMyObject
实例的
TMyObject
构造函数?换句话说,我想排除从
TObject
或其他不能用于正确初始化
TMyObject
的祖先继承的构造函数。有没有办法使用 RTTI 来识别并过滤掉这些不合适的构造函数?

任何指导或建议将不胜感激。

delphi rtti
1个回答
2
投票

就像您注意到的那样,

GetMethods
中的
TRttiType
函数收集类层次结构中的所有方法。

但是

GetDeclaredMethods
中还有另一种方法
TRttiType
,它将仅检索以特定类型声明的方法,并且不会沿着祖先列表向下查找。但是,此函数没有允许您按名称过滤方法的参数,因此要获得您需要的内容,您需要编写额外的过滤函数。

类似:

function GetDeclaredMethods(AType: TRttiType; const AName: string): TArray<TRttiMethod>;
var
  Methods: TArray<TRttiMethod>;
  Method: TRttiMethod;
begin
  SetLength(Result, 0);
  Methods := AType.GetDeclaredMethods;
  for Method in Methods do
    begin
      if Method.HasName(AName) then
        begin
          SetLength(Result, Length(Result) + 1);
          Result[High(Result)] := Method;
        end;
    end;
end;

在上面的函数中添加方法没有得到优化,所以你可能想要优化该部分,但它也不是非常低效,除非你在类中声明了大量同名的重载方法。

© www.soinside.com 2019 - 2024. All rights reserved.