使用SuperObject将JSON反序列化为具有接口字段的对象

时间:2012-09-12 14:15:43

标签: json delphi interface deserialization superobject

我无法在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

如果有人在那里解决了这个问题,那肯定会很棒。谢谢! :)

0 个答案:

没有答案