我无法在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
的值,显然两者不匹配(我正在测试ITest
,还记得吗?)。所以我有点迷失于此。反序列化由一个或多个接口字段组成的任何对象是否违法?
这看起来像是一个常见的用例,我觉得很难相信。我可以理解这样一个事实,即知道要选择的给定接口的实现可能并非易事。然而,我从序言中的评论中看到,应该支持接口对象 - http://code.google.com/p/superobject/source/browse/trunk/superobject.pas#47。
如果有人在那里解决了这个问题,那肯定会很棒。谢谢! :)