3

SuperObject 和 TJson.ObjectToJsonObject 表示类的某些部分(即记录字段)的方式不一致。让我们有以下代码片段:

Uses rest.json, superobject;

  type

      TSimplePersonRec = record
        FirstName: string;
        LastName: string;
        Age: byte;
      end;

      TSimplePerson = class
        protected
          FPersonRec: TSimplePersonRec;
        public
          property personRecord: TSimplePersonRec read FPersonRec write FPersonRec;
      end;

    // ...

        { Public declarations }
        function toJson_SO(simplePerson: TSimplePerson): string;
        function toJson_Delphi(simplePerson: TSimplePerson): string;

    // ...

    function TForm1.toJson_Delphi(simplePerson: TSimplePerson): string;
    begin
      result := tjson.Format(TJson.ObjectToJsonObject(simplePerson));
    end;

    function TForm1.toJson_SO(simplePerson: TSimplePerson): string;
    var
      so: ISuperObject;
      ctx: TSuperRttiContext;
    begin
      ctx := TSuperRttiContext.Create;
      try
        so := ctx.AsJson<TSimplePerson>( simplePerson );
      finally
        ctx.Free;
      end;
      result := so.AsJSon(true, true);
    end;

    // ...

    procedure TForm1.Button3Click(Sender: TObject);
    var
      spr: TSimplePersonRec;
      sp: TSimplePerson;
    begin

      spr.FirstName := 'John';
      spr.LastName := 'Doe';
      spr.Age := 39;

      sp := TSimplePerson.Create;
      sp.personRecord := spr;

      memo1.Lines.Add(#13'--- SuperObject ---'#13);
      memo1.Lines.Add(toJson_SO(sp));
      memo1.Lines.Add(#13'---   Delphi    ---'#13);
      memo1.Lines.Add(toJson_Delphi(sp));
    end;

输出是:

--- SuperObject ---
{
 "FPersonRec": {
  "LastName": "Doe",
  "Age": 39,
  "FirstName": "John"
 }
}
---   Delphi    ---
{
  "personRec":
  [
    "John",
    "Doe",
    39
  ]
}

Delphi 将记录表示为 JSON 数组的原因是什么?是否有导致这种情况的公共标准或建议?

注意: 对我来说,用 {key: value} 表示法而不是数组来表示记录更自然。不知道值所属的键名可能会在反序列化期间产生奇怪的结果。例如,在反序列化期间,我可以传递一个具有相同布局的新类,其中包含具有不同内存布局的记录。在这种情况下,这些值将被随机分配或可能发生 AV?

更新: 我正在使用 Delphi XE7。我也发现了这个 json.org:

JSON 建立在两种结构之上:

  • 名称/值对的集合。在各种语言中,这被实现为对象、记录、结构、字典、哈希表、键控列表或关联数组。
  • 值的有序列表。在大多数语言中,这被实现为数组、向量、列表或序列。

所以问题可能更多是关于这是 TJson 单元中的错误吗?

4

1 回答 1

1

Delphi 输出是合法的 JSON。在内部,REST.TJson被硬编码以将记录编组为 JSON 数组。这就是它的实现方式,它是设计使然,而不是错误。这只是表示数据的另一种方式。SuperObject 选择更明确。那也没关系。两种不同的实现,两种不同的表示。JSON 规范允许两者。

于 2014-09-14T17:02:24.160 回答