【问题标题】:How to create a generic json deserialization factory如何创建一个通用的 json 反序列化工厂
【发布时间】:2020-03-14 09:28:39
【问题描述】:

我有一个场景,我将 json 作为字符串接收。除了其中的项目集合之外,每条 json 的格式都相同。以此作为简化示例:

{ 
    "Type": "A",
    "Items": [
       { "Name": "Item 1" },
       { "Name": "Item 2" }
    ]
}
{ 
    "Type": "B",
    "Items": [
       { "Counter": 1 },
       { "Counter": 2 }
    ]
}

我在代码中有以下模型来表示这一点:

public enum Type
{
    A, B
}
public class InstanceTypeA
{
    public string Name { get; set; }
}
public class InstanceTypeB
{
    public int Counter { get; set; }
}

注意:将来,类型将进一步扩展,例如本例中的 D、E 和 F。所有这些都将再次具有不同结构的项目集合。

而我想把它反序列化成一个模型,例如:

public class Container<T>
{
    public Type Type { get; set; }
    public List<T> Items { get; set; }
}

其中 T 可以是 instanceTypeA 或 instanceTypeB

如前所述,我收到顶部显示的 json 作为字符串。它是“类型”枚举,它决定了项目集合中保存的对象的类型。我正在努力寻找一种非常通用的方法来实现这种序列化。

我认为工厂模式可以提供帮助,但不确定如何实现 - 有没有人解决过类似的问题。

在我的代码中,在实际尝试序列化之前,我碰巧知道它是 A 型、B 型等。我可以这样做:

switch(obj.Type) 
{
   case A: JsonConvert.DeserializeObject<Container<A>>(obj.Json)
   case B: JsonConvert.DeserializeObject<Container<B>>(obj.Json)
}

这种方法的缺点是调用代码需要知道它处理Container&lt;A&gt;Container&lt;B&gt; 等。这根本不是通用的。我无法让 A 或 B 实现一个通用接口,因为它们都完全不同。对此有点困惑 - 我希望工厂模式可以提供帮助,但看不到如何 - 以前有没有人处理过类似的问题?

提前感谢您的任何指点!

【问题讨论】:

标签: c# .net json .net-core deserialization


【解决方案1】:

您不想使用Type 属性来指定使用的类型。使用 Newtonsoft Json 序列化程序时,您可以在 JSON 文档中包含对象的类型。这样,当序列化程序反序列化字符串时,它将了解要使用的类型。因此,您可以完全删除 Type 属性,只需检查数组中对象的类型。我相信您需要设置传递给序列化程序的设置对象的TypeNameHandling 属性。一旦您看到序列化程序在 JSON 字符串中输出带有您的对象的 $type 属性,您就知道您做对了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    • 2022-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多