首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将TValue传递给泛型方法

将TValue传递给泛型方法
EN

Stack Overflow用户
提问于 2017-03-16 23:34:55
回答 1查看 1K关注 0票数 2

我需要使用RTTI遍历一个具有复杂结构的类。这个类有几个记录成员,我也想迭代它们。

代码语言:javascript
运行
复制
 TRTTIHelpers<T> = class
  public
    class function DoGetValuesForClass(aClassInst: T): TStringList;
    class function DoGetValuesForRecord(aRec: T): TStringList;
  end;

我知道当我在班上有一个成员时,这是一个记录:

代码语言:javascript
运行
复制
   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

如何将TValue作为参数传递给DoGetValuesForRecord,以便也可以遍历记录?

EN

Stack Overflow用户

回答已采纳

发布于 2017-03-16 23:40:29

使用TValueAsType方法将值转换为T

代码语言:javascript
运行
复制
lValue := prop.GetValue(aInst);
Result.AddStrings(TRTTIHelpers<T>.DoGetValuesForRecord(lValue.AsType<T>));

这个简单的程序演示了这一点:

代码语言:javascript
运行
复制
{$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.

当然,这确实要求属性prop的类型正确。如果不是,那么你将会遇到一个运行时错误。在上面的示例中,我通过测试属性的名称来确保获得所需的属性。如果删除该测试,则程序将失败,并显示运行时EInvalidCast错误。

查看您的代码,我怀疑您很可能会遇到这样的错误。如果rt的每一个属性都是同一类型的,我会很惊讶。

看看TRTTIHelpers<T>,我不认为它目前的形式对你有多大用处。至少,它不会与基于RTTI的代码很好地交互。原因是对TRTTIHelpers<T>的调用要求您在编译时提供类型参数。但是对于RTTI代码,您在编译时不知道该类型。我怀疑TRTTIHelpers<T>可能不应该是一个泛型类,而应该使用RTTI类型为您提供灵活的运行时确定类型的功能。这个建议当然可能是错误的,但我只有问题中的一些代码摘录来指导我。

票数 7
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42838488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档