2012-09-19 7 views
3

xml 변환기에 대한 사용자 지정 클래스를 작업 중이며 요구 사항 중 하나는 TObjectList<T> 필드를 스트리밍하는 것입니다.
ToArray() 메서드를 호출하여 TObjectlist의 개체를 가져 오는 중입니다. 그러나 형식이 분명히 일치하지 않으므로 '잘못된 클래스 형식 변환'이 나타납니다. Delphi Rtti : TObjectList에서 개체를 가져 오는 방법 <T>

예를 들어,이 클래스를 가지고 :

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와에서 개체를 얻을 수 있습니다. 나는 어쩌면, 제안 오픈 오전

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; 

: 나는 TypInfo에 준 getItem/SetItem 방법을 참조하지 않는 일부 이상한 이유로 다윗

편집

덕분에 내 해결책을 가지고 있습니다 이 목표를 달성하기 위해 더 '영리한'방법이 있습니다 ...

+0

을 왜 배열의 항목을 넣어해야합니까? 대신에 각 항목을 하나씩 읽으려면'GetItem'을 호출 할 수 있습니까? 'T'를 알 필요없이 결과를'TObject'에 저장할 수 있습니다. –

+0

@RobKennedy, 어떤 이유로 typeinfo.GetMethods()를 반복 할 때 메소드를 찾지 못했습니다. – whosrdaddy

답변

4

동적 배열이 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;