Delphi Rtti:如何从 TObjectList 获取对象

2024-02-21

我正在开发一个自定义类到 xml 转换器,要求之一是能够进行流式传输TObjectList<T> fields.
我正在尝试调用ToArray()方法来获取 TObjectlist 的对象,但我得到“无效的类类型转换”,因为类型显然不匹配。

以这个类为例:

type
  TSite = class
    Name : String;
    Address : String; 
  end;

  TSites = class
    Sites : TObjecList<TSite>;
  end;  

我只需要从站点 TObjectList 获取站点对象。 请记住,我正在使用 RTTI,所以我不知道 TObjectList 中的 ObjectType,所以类型转换不起作用。这就是我所拥有的,但它似乎是一个死胡同(Obj 是TobjectList<TSite> here):

function TXmlPersister.ObjectListToXml(Obj : TObject; Indent: String): String;

var
  TypInfo: TRttiType;
  meth: TRttiMethod;
  Arr  : TArray<TObject>;

begin
 Result := '';
 TypInfo := ctx.GetType(Obj.ClassInfo);
 Meth := TypInfo.GetMethod('ToArray');
 if Assigned(Meth) then
  begin
   Arr := Invoke(Obj, []).AsType<TArray<TObject>>; // invalid class typecast error

   if Length(Arr) > 0 then
    begin
     // get objects from array and stream them
     ...
    end;
  end;

任何通过 RTTI 从 TObjectList 中获取对象的方法对我来说都是有好处的。 由于某些奇怪的原因,我在 TypInfo 中没有看到 GetItem/SetItem 方法

EDIT

感谢大卫,我有了我的解决方案:

function TXmlPersister.ObjectListToXml(Obj : TObject; Indent: String): String;

var
  TypInfo: TRttiType;
  meth: TRttiMethod;
  Value: TValue;
  Count : Integer;

begin
 Result := '';
 TypInfo := ctx.GetType(Obj.ClassInfo);
 Meth := TypInfo.GetMethod('ToArray');
 if Assigned(Meth) then
  begin
   Value := Meth.Invoke(Obj, []);
   Assert(Value.IsArray);
   Count :=  Value.GetArrayLength;
   while Count > 0 do
    begin
     Dec(Count);
     Result := Result + ObjectToXml(Value.GetArrayElement(Count).AsObject, Indent);
    end;
  end;
end;

我愿意接受建议,也许有更多“聪明”的方法来实现这个目标......


您的代码失败,因为动态数组不是 TObject。

你可以这样做:

Value := Meth.Invoke(Obj, []);
Assert(Value.IsArray);
SetLength(Arr, Value.GetArrayLength);
for i := 0 to Length(Arr)-1 do
  Arr[i] := Value.GetArrayElement(i).AsObject;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Delphi Rtti:如何从 TObjectList 获取对象 的相关文章

随机推荐

  • 多对多关系的3表之间的SQL查询

    我有三张桌子 friends locations friend location friend location是一个连接表 允许多对多关系friends and locations 所以表格看起来像这样 Friends ID Name 1
  • WooCommerce:管理员手动创建订单时需要挂钩

    我的网站之一使用 WooCommerce 客户有时希望在订单管理中手动创建订单 WooCommerce gt 订单 gt 添加订单 当他们单击该页面上的 保存订单 时 我需要对订单进行一些额外的处理 有可用的钩子吗 我浏览了 WooComm
  • Microsoft 聊天机器人 (Node.js) 是否在单个 LUIS.AI 应用程序中支持多种语言?

    我有一个使用 Node js 在 Microsoft 机器人框架中构建的聊天机器人 并将该机器人与名为 LUIS AI 智能的 NLP 框架集成 以根据用户的意图和实体处理用户对话 在这里 我需要这个机器人在单个 LUIS 应用程序中支持多
  • awk 查找重叠

    我有一个包含列的文件 如下所示 Group Start End chr1 117132092 118875009 chr1 117027758 119458215 chr1 103756473 104864582 chr1 10509379
  • 寻找 C++ 中搜索和替换的圣杯

    最近 我正在寻找一种替换字符串中标记的方法 这本质上是查找和替换 但至少还有一种解决问题的方法 看起来像是相当平庸的任务 我已经提出了几种可能的实现 但从性能的角度来看 它们都不能令人满意 最好的成绩是每次迭代约 50us 这种情况很理想
  • 如何从构造函数内的原型对象检索属性

    我认为这个问题本身就很解释 我正在尝试检索构造函数对象内原型对象内部的特定属性 如果我无法检索它 我希望有人能解释为什么我不能检索它 这是来自的代码jsfiddle https jsfiddle net 786ze44b JavaScrip
  • 缩放级别 15 相当于什么?

    出于某种原因 这似乎比我想象的更难找到 我正在使用地图显示 并将缩放级别设置为 15 mapController setZoom 15 不同的缩放级别等于多少距离 我假设是某种对数或指数尺度 如果我选择 1 或 18 作为缩放级别 则地图上
  • DBIx::Class 中的子查询

    我在这上面花了太多时间 但仍然无法让语法起作用 这个 select 语句可以在 DBIx Class 中使用吗 SELECT A id A name count C a id AS count1 SELECT count B id FROM
  • Matplotlib 动画使用 ArtistAnimation 更新标题

    我正在尝试使用 ArtistAnimation 来创建动画 一切都正常 除了set title不工作 我不明白为什么blit False不起作用 我需要去吗 函数动画 https stackoverflow com questions 44
  • 如何为 Angular 6 Bootstrap 4 modal 进行茉莉花单元测试用例

    html
  • 使用 jQuery 重新排序和动画列表项?

    所以 我有一个项目列表 例如 ul li List item 1 li li List item 2 li li List item 3 li ETC 定期触发 ajax 调用 我可能需要重新排序列表 通过使较低的项目之一成为列表中的第一个
  • 使用 C++ 调用不正常地重新启动 Mac OS X?

    如何使用以下命令重新启动 Mac OS XC 不是 Objective C 而不调用任何子进程 不在乎是不是不优雅的 system reboot Is not acceptable as it relies on invoking a pr
  • Oracle复合主键/外键问题

    我在 Oracle 的 1 个表中有一个复合主键 我想为第二个表中的一个表条目创建一个外键 该外键引用第一个表中的复合主键 我收到错误 ORA 02256 关于如何进入这个有什么想法吗 CREATE TABLE groupspersonx
  • Java:如何在 Spring 框架中声明嵌套映射?

    例如 您将如何声明一个三重映射 例如 Map
  • 为什么 PyCharm 在此处使用 @property 时会发出警告?

    在教程中 我看到了两种用于使用 property 的实例属性命名类型 这是显示两者示例的代码 它们的工作方式似乎也不同 class A def init self x self x x property def x self return
  • 循环内部 lambda

    我需要尽可能简化我的代码 它需要是一行代码 我需要在 lambda 表达式中放置一个 for 循环 如下所示 x lambda x for i in x print i 以防万一 如果有人正在寻找类似的问题 这里给出的大多数解决方案都是一行
  • 如何像instance_eval方法一样在块中更改self?

    instance eval 方法在其块中更改 self 例如 class D end d D new d instance eval do puts self print something like
  • 500 服务器错误的角度处理

    如何修改我的 http 调用以处理 捕获 500 个服务器错误 我尝试调用 API 但在函数的 err 部分收到 500 内部服务器错误 如果可能的话 我希望能够捕获它 但不确定如何捕获 有没有一种简单的方法可以做到这一点 call htt
  • WiFi TCP 连接从桌面传输到 Android 的垃圾数据

    我一直在四处寻找 但无法找到解决这个特定问题的方法 如果这是一个新手错误 请原谅我 我刚从学校毕业 所以我正在阅读尽可能多的书籍来赶上移动设备编程 目标 将数据从基于 PC 的套接字服务器无线传输到基于 Android 的客户端 802 1
  • Delphi Rtti:如何从 TObjectList 获取对象

    我正在开发一个自定义类到 xml 转换器 要求之一是能够进行流式传输TObjectList