【问题标题】:SuperObject Serializes Private Variables instead of PropertiesSuperObject 序列化私有变量而不是属性
【发布时间】:2012-06-03 08:14:54
【问题描述】:

我有以下代码可以序列化一个动态的类数组。出于某种原因,SuperObject 序列化私有变量而不是类属性名称。谁能建议如何在 SuperObject 中解决此问题?

class function TJSON.AsJSON<T>(AObject: T; Indent: Boolean = False): string;
var
  Ctx: TSuperRttiContext;
begin
  Ctx := TSuperRttiContext.Create;
  try
    Result := Ctx.AsJson<T>(AObject).AsJSon(Indent);
  finally
    Ctx.Free;
  end;
end;

type
  TMyClass = class
  private
    FName_: String;
    FAge_: Integer;
  public
    property Name: String read FName_ write FName_;
    property Age: Integer read FAge_ write FAge_;
  end;

procedure TFormTest.Button27Click(Sender: TObject);
var
  MyClassArray: TArray<TMyClass>;
  MyClass1, MyClass2: TMyClass;
begin
  MyClass1 := TMyClass.Create;
  MyClass1.Name := 'Joe';
  MyClass1.Age := 10;

  MyClass2 := TMyClass.Create;
  MyClass2.Name := 'Dan';
  MyClass2.Age := 13;

  SetLength(MyClassArray, 2);
  MyClassArray[0] := MyClass1;
  MyClassArray[1] := MyClass2;

  Memo1.Text := TJSON.AsJSON<TArray<TMyClass>>(MyClassArray);
end;

以上代码生成如下 JSON:

[{"FName_":"Joe","FAge_":10},{"FName_":"Dan","FAge_":13}]

我所追求的是以下 JSON:

[{"Name":"Joe","Age":10},{"Name":"Dan","Age":13}]

【问题讨论】:

  • 不确定是否有帮助,但也许您应该尝试将属性设置为published 而不是public
  • 除了 Pateman 的评论,我建议阅读文档(如果有的话)、演示和源代码
  • 我也同意在序列化过程中使用属性会更好。我已经在此发布了一个问题:code.google.com/p/superobject/issues/detail?id=61,因为绕过任何属性设置器可能会成为问题。 Rest.Json.TJson 也适用于属性。

标签: json delphi pascal rtti superobject


【解决方案1】:

我认为目前不可能,您可能点击了this issue。即使是 JSON 编组中的 Delphi XE2 Datasnap serializes private 字段,在我看来,这只是在不考虑限制的情况下为新扩展 RTTI 提供了更深入的可见性的结果。

【讨论】:

  • 我没有调查过这个问题,但是 TLama 所说的看起来是合法的,如果你不一定需要使用类,请切换到记录,因为它们似乎工作正常(至少通过查看演示)。
  • 我在此发布了一个问题:code.google.com/p/superobject/issues/detail?id=61,因为绕过任何属性设置器都可能成为问题。
【解决方案2】:

据我所知,RTTI 仅对 published 属性起作用(我可能错了),但我认为您应该简单地将属性访问级别切换为 published 以获得所需的 JSON 字符串。

【讨论】:

  • “经典”RTTI(Delphi 直到 2009 年)是有限的。 Delphi 2010 引入了能够访问私有字段的“扩展 RTTI”。
  • 你是对的,旧式 RTTI 只能访问 published 字段,但是问题中的代码示例中使用的 TSuperRttiContext 类可以从 Delphi 2010 开始使用,因为 @ 987654321@ 条件定义,见the source。所以上面的代码甚至在 2010 年以下的 Delphi 上都无法编译。
猜你喜欢
  • 1970-01-01
  • 2012-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-27
  • 1970-01-01
  • 1970-01-01
  • 2014-07-23
相关资源
最近更新 更多