我可以依靠通过 JsonSerializer 读取的节点顺序吗?

Can I rely on the order of nodes read via the JsonSerializer?

我读过这里 Is the order of elements in a JSON list preserved?

Json 中的顺序很重要

我也看过这里 Does List<T> guarantee insertion order? 保证 C# 泛型列表中的插入顺序

因此我可以假设当我使用 newtonsoft JsonSerializer 来读取这个 Json

 "answers": [
            {
                "choice": "36"
            },
            {
                "choice": "50"
            }
        ]

在具有 属性 'Answers' 类型的 GenericList 的对象中,Answers[0] 总是 returns 36,而 Answers[1] 总是 returns 50 ?

或者 JsonSerializer 是否可以随机播放数据?

我问的原因是我从外部 API 读取数据,他们说 "you should only get 1 answer back, but when you get more, use the last one",最后一个是文本中的最后一个,因此在本例中为“50”。

是的,您可以依赖通过 JsonSerializer 读取的数组节点的顺序。 JSON 数组被定义为 有序的值集合。,并且 Json.NET 将按照它们在 [=] 中遇到的顺序将它们添加到您的集合中98=] 文件。

这可以通过检查来验证 source code. The method JsonSerializerInternalReader.CreateList() 是负责集合反序列化的顶级方法,并且具有三种基本情况:

  1. 当反序列化为 read/write 集合时,ICollection.Add()(或 ICollection<T>.Add())将按照从 [=98] 中读取值的顺序调用=] 流,从而保留 JSON 数组顺序。这可以在 JsonSerializerInternalReader.PopulateList() 中看到。

    (当集合缺少非泛型 Add(object value) 方法时,将创建一个 CollectionWrapper<T> 来处理转换为所需参数类型,但这根本不会影响算法,因为包装器立即调用基础集合的 Add(T Value) 方法。)

  2. 当反序列化为 .Net 数组时,会为某些适当的 T 创建一个临时 List<T> 并按照情况 1 中遇到的顺序添加值,或者通过JsonSerializerInternalReader.PopulateList()JsonSerializerInternalReader.PopulateMultidimensionalArray(). Subsequently the list is converted to an array afterwards by calling either Array.CreateInstance then List<T>.ICollection.CopyTo(Array, Int32), or CollectionUtils.ToMultidimensionalArray()。两者都创建了保留传入集合值顺序的数组。

  3. 反序列化不可变集合时,集合必须有一个采用 IEnumerable<T> 的构造函数,其中 T 是集合项类型。这在 release notes for Json.NET 6.0.3 中有解释:

    To all future creators of immutable .NET collections: If your collection of T has a constructor that takes IEnumerable<T> then Json.NET will automatically work when deserializing to your collection, otherwise you're all out of luck.

    假设您的不可变集合具有所需的构造函数,算法将按照情况 2 进行,反序列化为 List<T>,然后使用值按照遇到和反序列化的顺序从列表中构造不可变集合。

当然,集合本身可能会打乱值的顺序:

但是对于基本集合 List<T>T [] 这不会发生。