2016-10-10 2 views
4

Учитывая следующий код:Newtonsoft.JSON: JSON Список и массив обрабатываются по-разному

public class ColorList 
{ 
    public List<string> Colors = new List<string>(new string[1] { "#eeeeee"}); 
} 
public class ColorArray 
{ 
    public string[] Colors = new string[1] { "#eeeeee"}; 
} 

public class Program 
{ 
    public static void Main() 
    { 
     string json = "{Colors:['#abc','#123']}"; 

     // Deserialize Colors into List: 
     Console.WriteLine(JsonConvert.DeserializeObject<ColorList>(json).Colors.Count); 
     // returns 3 
     // Deserialize Colors into Array: 
     Console.WriteLine(JsonConvert.DeserializeObject<ColorArray>(json).Colors.Length); 
     // returns 2 
    } 
} 

Почему существует разница между этими двумя deserializations?

+2

Похоже, что он добавляет в список (потому что он может), но заменяет весь массив (потому что он ничего не может сделать, хотя, я думаю, он может скопировать исходные значения). Если вы просто измените свой код, чтобы новый созданный объект не имел никаких записей, вы должны быть в порядке. –

+0

Я пробовал ваш код, и @JonSkeet кажется правильным. В списке нет проблем с добавлением новых значений, но в массиве вы должны воссоздать его, поскольку как только он имеет измерение, он не может быть (легко) изменен. Во всяком случае, это действительно неожиданное поведение для меня, поскольку я ожидал бы новую коллекцию при десериализации. – Pikoh

+0

Имеет ли смысл, что сериализатор и десериализатор не являются обратными функциями? Может ли сериализатор и десериализатор быть обратным, считаться ошибкой? – Alexander

ответ

3

В дополнение к Jon тарелочкам комментарий, хочу добавить, что вы можете частично контролировать это поведение:

var settings = new JsonSerializerSettings() { 
    ObjectCreationHandling = ObjectCreationHandling.Replace 
}; 
Console.WriteLine(JsonConvert.DeserializeObject<ColorList>(json, settings).Colors.Count); // returns 2, because list was replaced, not reused 

Однако, даже если вы будете использовать ObjectCreationHandling.Reuse с массивом - он не будет использовать его, но все-таки заменит (ну, в любом случае, он не может его повторно использовать).

Поскольку вы написали, что ожидаете новую коллекцию при десериализации - это может вам помочь.

+0

Я не знал, что настройка, спасибо – Pikoh

 Смежные вопросы

  • Нет связанных вопросов^_^