C# JSON-демаршализованные объекты в пользовательском классе для использования в циклах foreach требуют IEnumerable.

Вопрос или проблема

Я загружаю пользовательский JSON в собственный класс-геттер/сеттер, однако у меня совсем нет опыта работы с IEnumerables, и я немного застрял.

Json:
{ 
 'Item1': {'a': value, 'b': value, 'c': []},
}

В будущем он может содержать больше одного Item#, но всегда будет включать A, B и C в этом стандартном формате.

Используя пакет NewtonSoft Json, я выполняю

JsonConvert.DeserializeObject<ConfigurationFile>(jsonConfig)

Класс ConfigurationFile – это мой собственный класс, который выглядит так:

public class ConfigurationFile
{
    public ItemInfo? item{ get; set; }
}

public class ItemInfo
{
    public string a{ get; set; }
    public string b { get; set; }
    public string[]? c { get; set; }
}

Вот где возникает проблема. Все элементы устанавливаются правильно, как ожидалось. Но в подготовке к будущему мне нужно считать и что-то сделать с каждым элементом A, B или C.

Ошибка, которую я получаю, заключается в том, что если я начну

foreach (ConfigurationFile item in loadedJson)
{
  ...сделать что-то с item.a ...
}

Тогда я получаю ошибку, что класс ConfigurationFile может использоваться в foreach, только если он реализует IEnumerate или IEnumerate, или имеет подходящий метод GetEnumerator.

В чем моя ошибка? Единственное предположение, которое я могу высказать, так это то, что мой пользовательский класс для геттера/сеттера будет работать только для одного элемента, и, следовательно, не может быть частью оператора for-each… но я не знаю, как это выяснить.

Прежде всего, JSON использует двойные кавычки ", поэтому ваш JSON должен выглядеть так:

{ 
    "Item1": {"a": "value", "b": "value", "c": []}
}

Для простоты я предполагаю, что массив, хранящийся в c, будет простым массивом строк, например: "c": ["value1", "value2"]

Таким образом, мы можем смоделировать объект как:

public class Model
{
    public string a { get; set; }
    public string b { get; set; }
    public string[] c { get; set; }
}

Затем в паре JSON "key": "value" ключ и значение имеют форму словаря, таким образом, ваш JSON можно рассматривать как словарь. Объединяя все вместе, вот фрагмент кода с рабочей десериализацией:

var rawJson = @"{ 
    ""Item1"": {""a"": ""value"", ""b"": ""value"", ""c"": []}
}";

var dict = JsonSerializer.Deserialize<Dictionary<string, Model>>(rawJson);

Ответ или решение

Для решения вашей проблемы с десериализацией JSON в C# и последующей итерацией через объекты, вам необходимо изменить структуру ваших классов и подход к десериализации. Давайте разберем по шагам, что нужно сделать.

Шаг 1: Изменение вашего JSON-формата

Ваш JSON должен использовать двойные кавычки, как показано ниже:

{ 
    "Item1": {"a": "значение_a", "b": "значение_b", "c": []}
}

Шаг 2: Создание необходимых моделей

С учетом структуры вашего JSON можно рассмотреть использование словаря, чтобы соответствовать множеству элементов с ключом. Ваша модель может выглядеть следующим образом:

public class ItemInfo
{
    public string A { get; set; }
    public string B { get; set; }
    public string[] C { get; set; }
}

Шаг 3: Десериализация JSON

Вместо того, чтобы создавать класс ConfigurationFile, используйте словарь, где ключами будут названия предметов (например, "Item1"), а значениями — экземпляры ItemInfo. Это позволит вам в будущем легко добавлять другие элементы в JSON.

Вот как это можно сделать:

using Newtonsoft.Json;
using System.Collections.Generic;

var jsonConfig = @"{ 
    ""Item1"": {""a"": ""значение_a"", ""b"": ""значение_b"", ""c"": []}
}";

var items = JsonConvert.DeserializeObject<Dictionary<string, ItemInfo>>(jsonConfig);

Шаг 4: Итерация по элементам

Теперь, когда у вас есть словарь, вы сможете использовать конструкцию foreach для итерации по элементам:

foreach (var item in items)
{
    var itemKey = item.Key; // ключ (например, "Item1")
    var itemValue = item.Value; // значение типа ItemInfo

    // Вы можете получить доступ к свойствам A, B и C
    Console.WriteLine($"Key: {itemKey}, A: {itemValue.A}, B: {itemValue.B}");

    // Пример работы с массивом C
    foreach (var cItem in itemValue.C)
    {
        Console.WriteLine($"C item: {cItem}");
    }
}

Итог

Эта структура позволяет вам легко адаптироваться к изменениям в вашем JSON, когда он будет содержать более одного элемента. Каждый новый элемент будет просто добавляться в словарь, и вы сможете перебирать их в цикле foreach, как показано выше.

Если у вас возникнут дополнительные вопросы или потребуется помощь с другими аспектами работы с JSON в C#, не стесняйтесь спрашивать.

Оцените материал
Добавить комментарий

Капча загружается...