我在使用 Delphi 10.3.
TTestRTTI = class
field1: integer;
end;
procedure testRTTI();
var
field : TRttiField;
fields: TArray<TRttiField>;
testInstance: TTestRTTI;
val: Integer;
begin
testInstance := TTestRTTI.Create();
testInstance.field1 := 5;
fields := TRttiContext.Create().GetType(TypeInfo(TTestRTTI)).GetFields();
for field in fields do begin
val := field.GetValue(@testInstance).AsInteger;
end;
// val is not 5 ?
OutputDebugString(PChar(val.ToString()));
end;
GetValue 似乎没有返回正确的信息。我做错了什么?
编辑:似乎 Delphi 返回的是 Long 而不是 Integer ?这是平台问题吗?我在 Windows 10 64 位上。
好吧,我的问题是我将地址直接传递给 GetValue。由于
testInstance
是一个类,所以这是行不通的。
问题是,在使用泛型时,传递任何一个都不起作用。因此,与其使用像 : 这样的通用程序,不如
procedure TMyClass.DoStuff<T>(a: T);
你需要:
procedure TMyClass.DoStuff<T>(a: Pointer);
然后您可以将
a
直接传递给PByte或GetValue。
TRttiField.GetValue
函数需要将指针传递给实例以获取字段的值。但是,您的实例是一个对象,对对象的引用已经是一个指针,您应该直接传递它,而不是检索它的地址。
更改以下行并从呼叫中删除
@
接线员:
val := field.GetValue(testInstance).AsInteger;
另一方面,如果您的
TTestRTTI
是记录而不是类,那么在将记录实例传递给 @
函数时,您确实需要使用 GetValue
运算符。
TTestRTTI = record
field1: integer;
end;
val := field.GetValue(@testInstance).AsInteger;