【问题标题】:Serialize and deserialize a hierarchy of a C# class to Json [duplicate]将 C# 类的层次结构序列化和反序列化为 Json [重复]
【发布时间】:2017-02-21 14:03:38
【问题描述】:

有没有办法序列化然后反序列化具有未知类型成员变量的类,该类型可能是简单值类型或包含类本身的实例?

public class A
{
    public dynamic Value { get; set; }//Value could be int or type A for example
}

public static class ASerializer
{
    public static string ToJson(A table)
    {
        return JsonConvert.SerializeObject(table);//using Json.Net
    }

    public static A FromJson(string json)
    {
        return JsonConvert.DeserializeObject<A>(json);
    }
}

public class Tests
{
    public static void TestASerialization()
    {
        var a = new A() { Value = 1 };
        var aa = new A { Value = a };
        var aaa = new A { Value = aa };
        var json = ASerializer.ToJson(aaa);
        var aaa2 = ASerializer.FromJson(json);

        var aa2 = (A)aaa2.Value;    //throws
    }
}

如果我序列化然后反序列化 aaa - 我无法将反序列化 aaa 的值转换回我得到的类型 A:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:无法将类型“Newtonsoft.Json.Linq.JObject”转换为 'A'

关于优雅地处理这种嵌套层次结构而不诉诸手工编码的任何建议? 似乎只适用于 A 类型为 A 的一个实例。

【问题讨论】:

  • 可以使用TypeNameHandling序列化多态属性,反序列化后保留类型。
  • 要将TypeNameHandling 应用于特定属性,请参阅here
  • 谢谢,我确实试过了,但显然没有正确使用 JsonSerializerSettings 和 TypeNameHandling = TypeNameHandling.All 的属性实现它

标签: c# json serialization json.net deserialization


【解决方案1】:

你没有投射你认为你在投射的东西。

在这种情况下,您实际上是将Value 属性转换为A。在访问该属性之前,您需要将 aaa2 实例包装在带有强制转换的参数中。

var aa2 = ((A)aaa2).Value; 

【讨论】:

  • 错字,并不真正相关,异常消息有点清楚
【解决方案2】:

Dynamic 主要是一种编译器技巧,我会推荐泛型。 @David L 的回答也是正确的。

public class A<T>
{
    public T Value { get; set; }
}

【讨论】:

  • 如何将泛型限制为仅值类型 int 和类型 A 给定?
  • A something = new A();某物.值 = 1; //没问题something.Value = "";//异常
  • 我的措辞不好,我的实际要求是 A 类保存一个值,该值可能是值类型或本身 - 我想防止使用任何其他类型。在我没有在上面添加的实际实现中,因为它与序列化问题无关,我将限制使用重载构造函数和访问器方法支持的可能类型范围。您上面的示例将允许某人创建一个包含任何类型的 A 实例。
猜你喜欢
  • 2021-05-06
  • 1970-01-01
  • 1970-01-01
  • 2012-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多