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

我可以依赖于通过JsonSerializer读取的节点顺序吗?,json,json.net,jsonserializer,Json,Json.net,Jsonserializer,我在这里读过 Json中的顺序很重要 我也在这里读过 保证C#generic list中的插入顺序 因此,当我使用newtonsoft JsonSerializer读取此Json时,是否可以假设 "answers": [ { "choice": "36" }, { "choice": "50" } ] 在具有属性“A

我在这里读过

Json中的顺序很重要

我也在这里读过 保证C#generic list中的插入顺序

因此,当我使用newtonsoft JsonSerializer读取此Json时,是否可以假设

 "answers": [
            {
                "choice": "36"
            },
            {
                "choice": "50"
            }
        ]
在具有属性“Answers”的对象(类型为GenericList)中,Answers[0]始终返回36,Answers[1]始终返回50

或者JsonSerializer是否可能对数据进行洗牌


我问这个问题的原因是我从外部API读取数据,他们说“你应该只得到一个答案,但是当你得到更多答案时,使用最后一个”,最后一个是文本中的最后一个,所以在本例中是“50”。

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

这可以通过检查来验证。该方法是负责集合反序列化的顶级方法,有三种基本情况:

  • 当反序列化到读/写集合时,
    ICollection.Add()
    (或
    ICollection.Add()
    )将按照从JSON流读取值的顺序被调用,从而保留JSON数组顺序。这可以从中看出

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

  • 当反序列化到.Net数组时,会为一些适当的
    T
    创建一个临时
    列表,并按照遇到的顺序添加值,如案例1所示,可以通过
    JsonSerializerInternalReader.PopulateList()
    或。随后,通过调用then或将列表转换为数组。两者都创建保留传入集合值顺序的数组

  • 反序列化不可变集合时,该集合必须具有一个构造函数,该构造函数采用
    IEnumerable
    ,其中
    T
    是集合项类型。下文对此进行了解释:

    对于不可变.NET集合的所有未来创建者:如果您的T集合有一个采用
    IEnumerable
    的构造函数,那么Json.NET将在反序列化到您的集合时自动工作,否则您就倒霉了

    假设您的不可变集合具有所需的构造函数,则该算法将像案例2一样进行,反序列化到
    列表
    ,然后从列表中使用遇到的值和反序列化的顺序构造不可变集合

  • 当然,集合本身可能会改变值的顺序:

    • 当反序列化到时,值将由集合动态重新排序

    • 反序列化到时,存在反序列化时堆栈顺序颠倒的已知问题:

      这里的问题是
      Stack
      实现了
      IEnumerable
      ,而不是
      ICollection
      ,因此Json.NET认为它是一个不可变的集合。幸运的是,它有一个单独的
      IEnumerable
      输入参数。不幸的是,由于它是一个堆栈,它在枚举时颠倒了输入的顺序

      有关详细信息,请参阅


    但是,对于基本集合
    List
    T[]
    而言,这不会发生。

    Json.NET在反序列化实现
    IList
    IList
    的类型(包括
    List
    或任何数组)时,不会改变元素顺序。它按遇到的顺序将它们插入列表(或集合)
    Stack
    会出现一些奇怪的问题,正如前面所解释的那样,但是这确实是唯一的例子,这是由于
    Stack
    的实现有点特殊,也就是说,枚举数反转传递给构造函数的项的顺序。这是你想要的答案,还是你需要文档/源链接?鉴于你在这个网站上给出的答案数量,我倾向于相信你知道JsonSerializer的详细信息。这是根据您自己的经验,还是您知道源代码?(去检查)对于读/写集合,您可以在中看到详细信息。当然,底层集合可能会重新排列项目,例如,图像填充
    SortedSet
    。我从来没想过自己查代码。好的。现在相信了!