DXE2でSuperObjectを使用してjsonからインターフェイスフィールドを含むオブジェクトを逆シリアル化するのに問題があります(シリアル化は正常に機能します)。次のことを考慮してください。
ITest = interface(IInterface)
['{9E5623FF-1BC9-4FFA-919D-80C45EE24F38}']
function GetField3() : string;
procedure SetField3(Value: string);
property FField3: string read GetField3 write SetField3;
end;
TTest = class(TInterfacedObject, ITest)
private
FField3: string;
function GetField3() : string;
procedure SetField3(Value: string);
public
property Field3: string read GetField3 write SetField3;
constructor Create(Field3: string);
end;
TMyClass = class(TObject)
public
FField1: string;
FField2: string;
FTest: ITest;
constructor Create(Field1: string; Field2: string; Test: ITest);
end;
// TTest-stuff omitted for brevity.
constructor TMyClass.Create(Field1, Field2: string; Test: ITest);
begin
FField1 := Field1;
FField2 := Field2;
FTest := Test;
end;
var
MyClass: TMyClass;
MyClass2: TMyClass;
JSONObj: ISuperObject;
SuperContext: TSuperRttiContext;
begin
MyClass := TMyClass.Create('Test1', 'Test2', TTest.Create('Test3'));
SuperContext := TSuperRttiContext.Create();
JSONObj := SuperContext.AsJson<TMyClass>(MyClass);
WriteLn(JSONObj.AsString);
MyClass2 := SuperContext.AsType<TMyClass>(JSONObj);
MyClass2.Free();
ReadLn;
end.
実行がフィールドのTSuperRttiContext.FromJson.FromClass
チェックにFTest
到達すると、doo-dooは天井のプロペラ(または、必要に応じてテーブルに取り付けられたもの)に当たります。この時点で、Result := FromJson(f.FieldType.Handle, GetFieldDefault(f, obj.AsObject[GetFieldName(f)]), v);
が呼び出され、SuperObject.pasコードの興味深い部分に移動します。簡潔にするために、ここで複製します。
procedure FromInterface;
const soguid: TGuid = '{4B86A9E3-E094-4E5A-954A-69048B7B6327}';
var
o: ISuperObject;
begin
if CompareMem(@(GetTypeData(TypeInfo).Guid), @soguid, SizeOf(TGUID)) then
begin
if obj <> nil then
TValue.Make(@obj, TypeInfo, Value) else
begin
o := TSuperObject.Create(stNull);
TValue.Make(@o, TypeInfo, Value);
end;
Result := True;
end else
Result := False;
end;
に割り当てられた値soguid
はの値ISuperObject
であるため、明らかに2つは一致しません(テスト中ですITest
、覚えていますか?)。だから私はこれをどうすればいいのか少し迷っています。1つ以上のインターフェイスフィールドで構成されるオブジェクトを逆シリアル化することは違法ですか?
これは非常に一般的な使用例のように思われるので、信じがたいです。選択する特定のインターフェースの実装を知ることは簡単ではないかもしれないという事実を理解することができます。それでも、前文のコメントから、インターフェイスされたオブジェクトがサポートされることになっていることがわかります-http://code.google.com/p/superobject/source/browse/trunk/superobject.pas#47。
誰かがこれを解決したなら、きっと素晴らしいでしょう。ありがとう!:)