【问题标题】:How to deserialize array of different types from JSON如何从 JSON 反序列化不同类型的数组
【发布时间】:2018-04-14 20:37:18
【问题描述】:

我的 JSON 字符串看起来像:

{
    "type": "group",
    "logicalOperator": "or",
    "conditions":[{
            "type": "condition",
            "metric": "CTR",
            "operator": ">=",
            "value": "123"
        },
        {
            "type": "group",
            "logicalOperator": "and",
            "conditions": [{
                "type": "condition",
                "metric": "CTR",
                "operator": ">=",
                "value": "123"
                }]
        }
    ]
}

我想将其反序列化为 C# 类(使用 Newtonsoft.JSON)。但是conditions 可以包含groupcondition 这一点对我来说是个问题。

public class Group {
    public string logicalOperator { get; set; }
    public List<object> conditions { get; set; }
}

public class Condition {
    public string metric { get; set; }
    public string @operator { get; set; }
    public int value { get; set; }
}

我怎样才能摆脱List&lt;object&gt;?蒂亚!

【问题讨论】:

标签: c# json


【解决方案1】:

你没有问题:

public class YourType
{
    public ConditionType Type { get; set; }
    public string Metric { get; set; }
    public string Operator { get; set; }
    public int Value { get; set; }
    public string LogicalOperator { get; set; }

    public List<YourType> Conditions { get; set; }
}

public enum ConditionType
{
    Group,
    Condition
}

然后像往常一样反序列化它

var result = JsonConvert.DeserializeObject<YourType>(yourJson);

您最终会得到一个具有枚举器 TypeYourType 类,您可以使用它来确定它是组还是条件。

如果是条件,则填写属性。

如果它是一个组,您的Conditions 内部列表包含其余部分。

【讨论】:

  • 感谢您的回答。我想到了那个变种。但我想检查 null 的属性以了解它是哪个类 - 不好的做法。尤其是当我们谈论诸如 C# (OOP) 之类的语言时
  • 您没有检查空值。您正在检查 Type 枚举属性
  • 啊,是的。错过了。好的,你。
【解决方案2】:

首先,C# 不会反序列化 json 字符串。 C# 可用于调用执行此操作的库。

基于纯粹的猜测,我会继续说您可能正在使用 Newtonsoft.Json 进行反序列化,尽管您很可能正在使用其他东西。让我们退后一步。

如果是这样,那么“摆脱”List&lt;object&gt; 将是您最不关心的问题。实际上,能够提出不只是空的实例,plain'ol System.Object 实例将是您的第一个挑战。这仅仅是因为告诉反序列化器你的超级(基本)类型是什么甚至不会让他们去寻找可能的子类型,因为任何类型的子类型都是一个开放集(任何人都可以在没有你感觉的情况下获取和引用你的程序集并扩展你的类任何东西)。

拥有System.Object 类型的引用列表,每个指向MyNamespace.GroupMyNamespace.Condition 类型的实例可能看起来很麻烦,直到您意识到拥有MyNamespace.Group 和另一个实例是这个特定的实际挑战您描述的用例。

再退一步,在 OOP 中,当您想要存储可能不同类型的实例的列表并且您的语言是强类型并提供某种泛型(包括 C#)时,您不能为 element 使用泛型参数不能从您希望实例可能成为的每一种特定类型中隐式分配的类型。在您的情况下,objectGroupCondition 兼容。如果这是你唯一的问题,那么你应该简单地创建一个第三类(我们称之为EitherGroupOrCondition)并使其成为自然发生的类层次结构的根(GroupCondition 现在都应该扩展EitherGroupOrCondition)。然后你可以把你的List&lt;object&gt; 变成List&lt;EitherGroupOrCondition&gt;

回到反序列化:您需要查看 JsonSerializerSettings.TypeNameHandling 和它的特性。

您应该考虑以下实现目标的先决条件:

  • 彻底了解 OOP
  • 了解您的特定 Json 反序列化器的功能(希望您使用的是 Newtonsoft.Json

这两个先决条件都需要时间和耐心,我鼓励您继续完成它们,不要盲目工作,至少不了解您正在使用的产品的建议产品表面。

【讨论】:

    猜你喜欢
    • 2022-01-19
    • 2021-09-08
    • 2014-06-30
    • 2016-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-15
    相关资源
    最近更新 更多