【发布时间】:2012-09-19 15:24:15
【问题描述】:
我正在使用自定义类到 xml 转换器,其中一项要求是能够流式传输 TObjectList<T> 字段。
我正在尝试调用 ToArray() 方法来获取 TObjectlist 的对象,但我得到“无效的类类型转换”,因为类型显然不匹配。
以这个类为例:
type
TSite = class
Name : String;
Address : String;
end;
TSites = class
Sites : TObjecList<TSite>;
end;
我只需要从站点 TObjectList 中获取站点对象。
请记住,我使用的是 RTTI,所以我不知道 TObjectList 中的 ObjectType,所以 Typecasting 不起作用。这就是我所拥有的,但它似乎是一个死胡同(这里的 Obj 是 TobjectList<TSite>):
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 方法
编辑
感谢大卫,我有我的解决方案:
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;
我愿意接受建议,也许有更“聪明”的方法来实现这个目标......
【问题讨论】:
-
为什么需要将项目放入数组中?你能不能只打电话给
GetItem而不是一一阅读每个项目?您可以将结果存储在TObject中,而无需知道T。 -
@RobKennedy,由于某种原因,我在迭代 typeinfo.GetMethods() 时找不到该方法;
标签: delphi generics delphi-xe rtti tobjectlist