c# - Json.net 反序列化为 Json 中可能包含数组或嵌套数组的对象

标签 c# json.net

我有许多正在使用的 JSon 文件进行反序列化

JsonSerializer 序列化器 = new JsonSerializer(); t obj = (t)serializer.Deserialize(file, typeof(t));

对象集合。除其他外,它们还包含以下数据。 “truthtable”中数组的数量由“gates”的值决定

"gates" : 1,
"truthtable" : [ false, true ]

"gates" : 2,
"truthtable" : [ [ false, false ], [ false, true ] ]

如果我尝试将“truthtable”反序列化为以下属性,示例 1 会失败。

public List<List<bool>>truthtable { get; set; }

有什么方法可以将这两种不同类型的真值表反序列化到同一个对象吗?我尝试过构建自定义反序列化器,但 Json 将两者视为“JsonToken.StartArray”,因此无法以这种方式进行区分。

理想情况下,我希望能够反序列化这两个示例,就好像它们是 bool 数组的数组一样。

编辑 应该提到的是,我无法改变 Json 文件的创建方式。我无权访问他们的创作。

最佳答案

这个问题可以使用自定义 JsonConverter 来解决。转换器可以读取门的数量,然后填充 List<List<bool>>因此。如果只有一个门,它可以将单个列表包装在外部列表中,以使其适合您的类(class)。

假设您尝试反序列化的类看起来像这样:

class Chip
{
    public int Gates { get; set; }
    public List<List<bool>> TruthTable { get; set; }
}

那么转换器可能看起来像这样:

class ChipConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(Chip));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);

        Chip chip = new Chip();
        chip.Gates = (int)jo["gates"];
        JArray ja = (JArray)jo["truthtable"];

        if (chip.Gates == 1)
        {
            chip.TruthTable = new List<List<bool>>();
            chip.TruthTable.Add(ja.ToObject<List<bool>>());
        }
        else
        {
            chip.TruthTable = ja.ToObject<List<List<bool>>>();
        }

        return chip;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

要使用转换器,请创建一个实例并将其添加到序列化器的 Converters 中反序列化之前的集合:

serializer.Converters.Add(new ChipConverter());

或者,如果您愿意,您可以使用 [JsonConverter] 来注释您的类。属性代替:

[JsonConverter(typeof(ChipConverter))]
class Chip
{
    ...
}

这是一个展示转换器实际运行的演示(请注意,我在这里使用 JsonConvert.DeserializeObject<T>() 而不是创建 JsonSerializer 实例,但它的工作方式相同):

class Program
{
    static void Main(string[] args)
    {
        string json = @"
        [
            {
                ""gates"": 1,
                ""truthtable"": [ false, true ]
            },
            {
                ""gates"": 2,
                ""truthtable"": [ [ false, false ], [ false, true ] ]
            }
        ]";

        List<Chip> chips = JsonConvert.DeserializeObject<List<Chip>>(json,
                                                         new ChipConverter());

        foreach (Chip c in chips)
        {
            Console.WriteLine("gates: " + c.Gates);
            foreach (List<bool> list in c.TruthTable)
            {
                Console.WriteLine(string.Join(", ",
                    list.Select(b => b.ToString()).ToArray()));
            }
            Console.WriteLine();
        }
    }
}

输出:

gates: 1
False, True

gates: 2
False, False
False, True

关于c# - Json.net 反序列化为 Json 中可能包含数组或嵌套数组的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21940989/

相关文章:

c# - 为 prod 和 dev 指定 asp.net core 1.0 WebAPI.exe 应该在 program.cs 中使用的 url(端口)

c# - 将具体实现作为通用返回

c# - 单元测试 C# [TestInitialize]

c# - 每周做某事的 MVC .NET Web 应用程序

c# - 从 Json 字符串中提取数据

c# - Json.Net 无法从动态对象反序列化为 nullable<short>

c# - 良好做法 : Loop And If statement

c# - 反序列化字符串不转换数组

C#如何给JsonProperty设置多个名字?

c# - 在 utf-8 json 上转义重音字符