Je travaille un convertisseur de classe en xml personnalisé et l'une des exigences est la possibilité de diffuser des champs TObjectList<T>
.
J'essaye d'invoquer la méthode ToArray()
pour obtenir les objets TObjectlist, mais j'obtiens une 'classe incorrecte' parce que les types ne correspondent pas.Delphi Rtti: comment obtenir des objets de TObjectList <T>
prendre cette classe par exemple:
type
TSite = class
Name : String;
Address : String;
end;
TSites = class
Sites : TObjecList<TSite>;
end;
J'ai juste besoin d'obtenir le site Objets du TObjectList Sites. S'il vous plaît gardez à l'esprit que j'utilise RTTI, donc je ne connais pas le ObjectType dans TObjectList, alors Typecasting ne fonctionnera pas. Voilà ce que j'ai, mais il semble une impasse (Obj est TobjectList<TSite>
ici):
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;
un moyen d'obtenir les objets de la TObjectList via RTTI est bon pour moi. Pour une raison étrange, je ne vois pas les méthodes GetItem/de SetItem dans TypInfo
EDIT
Merci à David j'ai ma solution:
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;
Je suis ouvert aux suggestions, peut-être Il existe d'autres moyens «intelligents» pour atteindre cet objectif ...
Pourquoi avez-vous besoin de mettre les éléments d'un tableau? Ne pourriez-vous pas simplement appeler 'GetItem' à la place pour lire chaque élément un par un? Vous pouvez stocker le résultat dans un 'TObject' sans avoir à connaître' T'. –
@RobKennedy, pour une raison quelconque, je ne trouve pas la méthode lors de l'itération sur typeinfo.GetMethods(); – whosrdaddy