カスタムクラスからxmlへのコンバーターを使用していますが、要件の1つはTObjectList<T>
フィールドをストリーミングする機能です。TObjectlistのオブジェクトを取得するため
にメソッドを呼び出そうとしていますが、タイプが明らかに一致しないため、「Invalidclasstypecast」が表示されます。ToArray()
このクラスを例にとってみましょう。
type
TSite = class
Name : String;
Address : String;
end;
TSites = class
Sites : TObjecList<TSite>;
end;
SitesTObjectListからSiteObjectsを取得する必要があります。私はRTTIを使用しているので、TObjectListのObjectTypeがわからないため、型キャストは機能しないことに注意してください。これは私が持っているものですが、行き止まりのようです(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;
私は提案を受け入れています、多分この目標を達成するためのより多くの「賢い」方法があります...