使用json.net反序列化时是否保留了数组顺序?

时间:2014-09-21 00:47:49

标签: c# json json.net

当我使用json.net库将json对象反序列化为c#对象时,是否会保持数组属性中元素的顺序?例如:

public class MySonsThreeFootRadius
{
    public Boolean IsMessy { get; set; }
    public Toy[] ToysThrownOnFloor { get; set; }
}

public class Toy
{
    public String Name { get; set; }
}

{
    "IsMessy": true,
    "ToysThrownOnFloor": [
        { "Name": "Giraffe" },
        { "Name": "Ball" },
        { "Name": "Dad's phone" }
    ]
}

ToysThrownOnFloor是否保留Giraffe,Ball和Dad手机的订单,还是可以重新订购?

2 个答案:

答案 0 :(得分:12)

这取决于您正在使用的收藏品。

任何实现IEnumerable / IEnumerable<T>的类都可以序列化为JSON数组。 Json.NET顺序处理集合,也就是说,它将按照集合从GetEnumerator返回的顺序序列化数组项,并按照从JSON文件反序列化的顺序将项添加到集合中(使用{{ 1}}可变集合的方法,以及带有不可变集合的集合参数的构造函数。)

这意味着如果集合保留了项目的顺序(AddT[]List<T>Collection<T>等),则序列化时将保留订单反序列化。但是,如果集合未保留项目的顺序(ReadOnlyCollection<T>等),则订单将丢失。

相同的逻辑适用于JSON对象。例如,序列化HashSet<T>时订单将丢失,因为此集合不会保留项目的顺序。

答案 1 :(得分:6)

json spec没有具体说明应该保留订单,而是说:

  

数组结构是一对围绕零的方括号令牌   或更多的价值观。值以逗号分隔。的顺序   价值是重要的。

该规范还指出:

  

JSON还提供对有序值列表的支持。所有   编程语言将具有一些表示这种语言的功能   列表,可以使用数组,向量或列表等名称。

json.net documentation开始,反序列化示例肯定会暗示要保留的顺序:

string json = @"[
  {
    'Name': 'Product 1',
    'ExpiryDate': '2000-12-29T00:00Z',
    'Price': 99.95,
    'Sizes': null
  },
  {
    'Name': 'Product 2',
    'ExpiryDate': '2009-07-31T00:00Z',
    'Price': 12.50,
    'Sizes': null
  }
]";

List<Product> products = JsonConvert.DeserializeObject<List<Product>>(json);

Console.WriteLine(products.Count);
// 2

Product p1 = products[0];

Console.WriteLine(p1.Name);
// Product 1

根据规范和json.net文档,可以安全地假设订单被保留。