RBA*_*RBA 2 delphi rtti delphi-10.1-berlin
我需要使用RTTI遍历具有复杂结构的类.该类有几个记录成员,我也想迭代.
TRTTIHelpers<T> = class
public
class function DoGetValuesForClass(aClassInst: T): TStringList;
class function DoGetValuesForRecord(aRec: T): TStringList;
end;
Run Code Online (Sandbox Code Playgroud)
我知道当我在课堂上有一个成员时,这是一个记录:
for prop in rt.GetProperties() do
begin
if prop.PropertyType is TRttiRecordType then
begin
lValue := prop.GetValue(aInst);
Result.AddStrings(TRTTIHelpers<T>.DoGetValuesForRecord(TValue)); <--
end
Run Code Online (Sandbox Code Playgroud)
如何将TValue作为参数传递给DoGetValuesForRecord,以便我也可以遍历记录?
使用AsType<T>方法TValue将值转换为T:
lValue := prop.GetValue(aInst);
Result.AddStrings(TRTTIHelpers<T>.DoGetValuesForRecord(lValue.AsType<T>));
Run Code Online (Sandbox Code Playgroud)
这个简单的程序演示了这个
{$APPTYPE CONSOLE}
uses
System.RTTI;
type
TMyRecord = record
foo: Integer;
end;
TMyClass = class
function GetRec: TMyRecord;
property Rec: TMyRecord read GetRec;
function GetInt: Integer;
property Int: Integer read GetInt;
end;
function TMyClass.GetRec: TMyRecord;
begin
Result.foo := 42;
end;
function TMyClass.GetInt: Integer;
begin
Result := 666;
end;
procedure Main;
var
inst: TMyClass;
ctx: TRttiContext;
typ: TRttiType;
prop: TRttiProperty;
value: TValue;
rec: TMyRecord;
begin
inst := TMyClass.Create;
typ := ctx.GetType(TypeInfo(TMyClass));
for prop in typ.GetProperties do begin
if prop.Name='Rec' then begin
value := prop.GetValue(inst);
rec := value.AsType<TMyRecord>;
Writeln(rec.foo);
end;
end;
end;
begin
try
Main;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
Run Code Online (Sandbox Code Playgroud)
当然,这确实要求属性prop的类型正确.如果没有,那么您将遇到运行时错误.在上面的例子中,我确保通过测试属性的名称来确保获得所需的属性.如果删除该测试,则程序将失败并显示运行时EInvalidCast错误.
看看你的代码,我怀疑你很可能会遇到这样的错误.如果每个属性rt属于同一类型,我会感到惊讶.
看着TRTTIHelpers<T>我不认为它对你目前的形式有用.至少,它不会与基于RTTI的代码很好地交互.原因是调用TRTTIHelpers<T>要求您在编译时提供类型参数.但是对于RTTI代码,您在编译时不知道该类型.我怀疑它TRTTIHelpers<T>应该不是通用类,而是使用RTTI类型为您提供灵活的运行时确定类型的功能.这个建议当然是错误的,但我只在问题中有一小段代码来指导我.
| 归档时间: |
|
| 查看次数: |
519 次 |
| 最近记录: |