3

SuperObject と TJson.ObjectToJsonObject がクラスの特定の部分 (つまり、Record フィールド) を表す方法には一貫性がありません。次のコード スニペットを見てみましょう。

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 は、次の 2 つの構造で構築されています。

  • 名前と値のペアのコレクション。さまざまな言語で、これはオブジェクト、レコード、構造体、辞書、ハッシュ テーブル、キー付きリスト、または連想配列として実現されます。
  • 値の順序付きリスト。ほとんどの言語では、これは配列、ベクトル、リスト、またはシーケンスとして実現されます。

おそらく問題は、これは TJson ユニットのバグですか?

4

1 に答える 1

1

Delphi の出力は正当な JSON です。内部的にREST.TJsonは、レコードを JSON 配列としてマーシャリングするようにハードコーディングされています。これは単に実装方法であり、バグではなく設計によるものです。これは、データを表すもう 1 つの方法です。SuperObject は、より明確にすることを選択します。それもOKです。2 つの異なる実装、2 つの異なる表現。JSON 仕様では、両方が許可されています。

于 2014-09-14T17:02:24.160 に答える