我可以依赖于通过JsonSerializer读取的节点顺序吗?
我在这里读过 Json中的顺序很重要 我也在这里读过 保证C#generic list中的插入顺序 因此,当我使用newtonsoft JsonSerializer读取此Json时,是否可以假设我可以依赖于通过JsonSerializer读取的节点顺序吗?,json,json.net,jsonserializer,Json,Json.net,Jsonserializer,我在这里读过 Json中的顺序很重要 我也在这里读过 保证C#generic list中的插入顺序 因此,当我使用newtonsoft JsonSerializer读取此Json时,是否可以假设 "answers": [ { "choice": "36" }, { "choice": "50" } ] 在具有属性“A
"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)
方法。)T
创建一个临时列表,并按照遇到的顺序添加值,如案例1所示,可以通过JsonSerializerInternalReader.PopulateList()
或。随后,通过调用then或将列表转换为数组。两者都创建保留传入集合值顺序的数组
IEnumerable
,其中T
是集合项类型。下文对此进行了解释:
对于不可变.NET集合的所有未来创建者:如果您的T集合有一个采用IEnumerable
的构造函数,那么Json.NET将在反序列化到您的集合时自动工作,否则您就倒霉了
假设您的不可变集合具有所需的构造函数,则该算法将像案例2一样进行,反序列化到列表
,然后从列表中使用遇到的值和反序列化的顺序构造不可变集合- 当反序列化到时,值将由集合动态重新排序
- 反序列化到时,存在反序列化时堆栈顺序颠倒的已知问题:
这里的问题是
实现了Stack
,而不是IEnumerable
,因此Json.NET认为它是一个不可变的集合。幸运的是,它有一个单独的ICollection
输入参数。不幸的是,由于它是一个堆栈,它在枚举时颠倒了输入的顺序 有关详细信息,请参阅IEnumerable
但是,对于基本集合
List
或T[]
而言,这不会发生。Json.NET在反序列化实现IList
或IList
的类型(包括List
或任何数组)时,不会改变元素顺序。它按遇到的顺序将它们插入列表(或集合)Stack
会出现一些奇怪的问题,正如前面所解释的那样,但是这确实是唯一的例子,这是由于Stack
的实现有点特殊,也就是说,枚举数反转传递给构造函数的项的顺序。这是你想要的答案,还是你需要文档/源链接?鉴于你在这个网站上给出的答案数量,我倾向于相信你知道JsonSerializer的详细信息。这是根据您自己的经验,还是您知道源代码?(去检查)对于读/写集合,您可以在中看到详细信息。当然,底层集合可能会重新排列项目,例如,图像填充SortedSet
。我从来没想过自己查代码。好的。现在相信了!