RTTI 不适用于实例化泛型类的方法

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

我正在尝试使用 Delphi 12.2 Pro 检索实例化泛型类的 RTTI 信息。

Delphi 文档指出 (https://docwiki.embarcadero.com/RADStudio/Athens/en/Overview_of_Generics):

运行时类型识别 在Win32中,泛型和方法不 具有运行时类型信息 (RTTI),但实例化类型确实具有 RTTI。

我可以获得实例化泛型类的字段和属性的 RTTI 信息。但是,我不能寻找方法。 下面是示例代码。 我是否遗漏了什么,或者这是一个错误?

program Project1;

{$M+}

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.Rtti;

type
  TTestObject<T> = class
  private
    FValue: T;
    function GetValue: T;
  public
    constructor Create(AValue: T);
    property Value: T read GetValue;
  end;

  TIntegerObject = class(TTestObject<Integer>)
  end;

{ TTestObject }

constructor TTestObject<T>.Create(AValue: T);
begin
  FValue := AValue;
end;

function TTestObject<T>.GetValue: T;
begin
  Result := FValue;
end;

var
  t: TRttiType;
  m: TRttiMethod;
  o: TIntegerObject;
  n: string;
begin
  try
    o := nil;
    n := '?';
    with TRttiContext.Create do
    try
      o := TIntegerObject.Create(10);
      t := GetType(o.ClassType);
      for m in t.GetMethods do
      begin
        if (m.name = 'GetValue') then
        begin
          n := m.Name;
          break;
        end;
      end;
      WriteLn('Name: ' + n); //writes "Name: ?"
      ReadLn;
    finally
      o.free;
      Free;
    end;
  except
    on E: Exception do
    begin
      Writeln(E.ClassName, ': ', E.Message);
      ReadLn;
    end;
  end;
end.
delphi generics rtti
1个回答
0
投票

您没有获得

GetValue
方法的 RTTI 信息,因为它被声明为
private
并且默认的 Delphi RTTI 配置不包括私有方法。

系统单元中有以下声明,然后在 RTTI 编译器指令中使用它来定义默认 RTTI 配置。

const
  { These constants represent the default settings built into the compiler.
    For classes, these settings are normally inherited from TObject. }
  DefaultMethodRttiVisibility = [vcPublic, vcPublished];
  DefaultFieldRttiVisibility = [vcPrivate..vcPublished];
  DefaultPropertyRttiVisibility = [vcPublic, vcPublished];

要更改代码中的可见性,您需要在每个单元中使用 RTTI 编译器指令,其中您希望它们与默认单元不同。

例如,使用以下命令将为所有内容启用 RTTI,并且您将获得

GetValue
功能的 RTTI。

{$RTTI EXPLICIT METHODS([vcPrivate..vcPublished]) PROPERTIES([vcPrivate..vcPublished]) FIELDS([vcPrivate..vcPublished])}

您可以在官方文档中找到有关具体设置以及如何使用 RTTI 的更多信息RTTI Directive

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