为什么JSON .Net不能序列化静态或const成员变量?
我无法在任何地方找到答案,但是当我尝试使用static或const成员变量序列化结构或类时,默认情况下它们不会序列化。 如果我尝试通过设置MemberSerialization.OptIn
强制序列化,我收到一个错误。
恩。
[JsonObject(MemberSerialization.OptIn)] public class Test { [JsonProperty] public int x = 1; [JsonProperty] public static int y = 2; }
如果我尝试使用以下命令序列化此类:
Test t = new Test(); string s = JsonConvert.SerializeObject( t );
我收到错误Error getting value from 'y' on 'Test'
。 如果y是const,也会发生同样的情况。
我的理论是静态和const值存储在内存中特殊的地方,并且由于某种原因,Json序列化器试图访问它们。 这完全是一种预感,我在C#Reference for Static中看不到任何帮助。 我对C#比较陌生 – 在这一点上,这真的是一个好奇的问题。
如果想要,它当然可以序列化静态变量。 通过使用Reflection API检查对象和类型来完成序列化,这些API允许您执行“任何操作” – 没有技术原因这些值无法序列化。
然而,有一个合乎逻辑的理由不支持默认情况:它没有多大意义。 您正在序列化一个实例 , static
或const
成员在逻辑上不是实例的一部分,而是整个类的一部分。
也就是说,如果它是属性,你仍然可以序列化static
成员:
[JsonProperty] public static int y { get; set; } // this will be serialized
当然,您可以通过创建自定义JsonConverter
来完全覆盖序列化程序的行为。
从Json.NET 6.0.4开始,静态和const成员变量以及静态属性在用[JsonProperty]
标记时将被序列化。 从发行说明 :
- 修复 – 修复了序列化静态字段
因此序列化以下类:
[JsonObject(MemberSerialization.OptIn)] public class Test { [JsonProperty] int x = 1; [JsonProperty] static int y = 2; [JsonProperty] const int z = 333; }
产生{"x":1,"y":2,"z":333}
。 示例小提琴 。
试试这个:
using Newtonsoft.Json; using System.Collections.Generic; using System.Linq; public static string SerializeStaticClass(System.Type a_Type) { var TypeBlob = a_Type.GetFields().ToDictionary(x => x.Name, x => x.GetValue(null)); return JsonConvert.SerializeObject(TypeBlob); }
我这样做是为了将所有静态类常量序列化为JS文件,然后将该文件捆绑到一个角度应用程序中。 将生成的js对象附加到$ rootScope,所有角度代码都可以访问常量。
帽子提示在这里
如果需要在每个实例上序列化静态成员(或const),则可以使用私有实例级访问器作为变通方法:
[JsonObject(MemberSerialization.OptIn)] public class Test { [JsonProperty] public int x = 1; // static member we want serialized with each instance public static int y = 2; // private accessor to allow Json.net to serialize the static member [JsonProperty("y")] private int y1 { get { return y; } } }
如果您还需要反序列化到此类,此方法将阻止Json.Net覆盖静态成员,同时仍允许您自己的代码在需要时修改它。