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

本文关键字:保留 数组 顺序 是否 json net 反序列化 使用 | 更新日期: 2023-09-27 18:23:56

当我使用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和爸爸手机的订单,或者可能会重新订购?

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

这取决于您使用的集合。

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

这意味着,如果集合保留项(T[]List<T>Collection<T>ReadOnlyCollection<T>等)的顺序,则在序列化和反序列化时将保留该顺序。但是,如果集合不保留项目的顺序(HashSet<T>等),则该顺序将丢失。

同样的逻辑也适用于JSON对象。例如,序列化Dictionary<TKey, TValue>时,顺序将丢失,因为此集合不保留项的顺序。

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

数组结构是一对围绕零的方括号标记或更多值。这些值用逗号分隔。的顺序价值是重要的。

规范还规定:

JSON还提供对有序值列表的支持。全部的程序设计语言将有一些特性来表示列表,可以使用数组、向量或列表等名称。

从json.net文档来看,反序列化示例肯定暗示了要保留的顺序:

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文档,可以放心地假设订单得到了保留。