我正在尝试使用 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.
您没有获得
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