3

我在 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-field 时,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;

分配给的值soguidISuperObject,所以很明显两者不匹配(我正在测试ITest,记得吗?)。所以我有点不知道该怎么做。反序列化由一个或多个接口字段组成的任何对象是否违法?

这似乎是一个常见的用例,我很难相信。我可以理解这样一个事实,即知道要选择给定接口的哪种实现可能并非易事。然而,我从序言中的评论中看到,应该支持接口对象 - http://code.google.com/p/superobject/source/browse/trunk/superobject.pas#47

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

4

0 回答 0