JSON Сериализация Dictionary

189
24 августа 2021, 05:00
[System.Serializable]    
public class SizeDBData
    {
        public string SizeName;
        public string Six_two_six;
        public string Foot_type;
        public string Fabric;
        public string RangeName;
    }

public Dictionary<string,Dictionary<string,List<SizeDBData>>> Sizes = new Dictionary<string, Dictionary<string, List<SizeDBData>>>();

Помогите плиз, как можно такое заджейсонить. Использую юнити. JsonUtility.ToJson(Sizes) не помогает

 foreach (var style in Styles)
 {
      yield return StartCoroutine(FetchSizeByStyle(style.StyleName));
 }
Debug.LogError(JsonUtility.ToJson(Sizes));
private IEnumerator FetchSizeByStyle(string _style)
    {
        UnityWebRequest uwr = UnityWebRequest.Get("url");
        yield return uwr.SendWebRequest();
        JSONObject obj = new JSONObject(uwr.downloadHandler.text);
        //List<SizeDBData> size = new List<SizeDBData>();
        foreach (var listItem in obj.list)
        {
            string style = listItem["range_name"].str;
            if (!Sizes.ContainsKey(style))
            {
                Sizes.Add(style, new Dictionary<string, List<SizeDBData>>());
            }
            string size = listItem ["size"].str;
            if (!Sizes[style].ContainsKey(size))
            {
                Sizes [style].Add(size,new List<SizeDBData>());
            }
            var sizeData = new SizeDBData(listItem ["size"].str,listItem ["six_two_six"].str,listItem ["foot_type"].str,listItem ["fabric"].str,listItem ["range_name"].str);
            Sizes [style][size].Add(sizeData);
        }
        //Sizes.Add(_style,size);
    }
Answer 1

Ну, самый простой вариант сериализуемого словаря с использованием Unity функционала выглядит примерно так:

[Serializable]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, ISerializationCallbackReceiver
{
    #region Fields
    [SerializeField]
    List<TKey> _keys;
    [SerializeField]
    List<TValue> _values;
    #endregion Fields
    #region Serialization
    void ISerializationCallbackReceiver.OnAfterDeserialize()
    {
        for (int i = 0; i < _keys.Count; i++)
        {
            var key = _keys[i];
            var value = _values[i];
            Add(key, value);
        }
        _keys.Clear();
        _values.Clear();
    }
    void ISerializationCallbackReceiver.OnBeforeSerialize()
    {
        _keys = new List<TKey>(Count);
        _values = new List<TValue>(Count);
        foreach (var item in this)
        {
            _keys.Add(item.Key);
            _values.Add(item.Value);
        }
    }
}

У него есть проблема с созданием мусорных массивов, если сам словарь большой - то он сначала создаст словарь под 0 значений. Потом под 4, 16 и т.д. другими словами несколько массивов элементов уйдут в сборщик мусора.

При этом словарь не имеет публичных методов для Resize-а. Я решал путём выковыривания метода через рефлексию.

READ ALSO
Как собрать выражение для конкатенации свойств произвольного класса?

Как собрать выражение для конкатенации свойств произвольного класса?

Хочу с помощью деревьев выражений LINQ сгенерировать делегат, который будет делать конкатенацию всех строковых свойств произвольного типа:

131
Как привести к generic типу?

Как привести к generic типу?

нельзя просто взять и привестиTType может быть int, string, etc

97
При уничтожении обьекта подвисает игра на Unity

При уничтожении обьекта подвисает игра на Unity

При уничтожении игрового объекта Destroy(gameobject); подвисает на секунду играПричина этому проклятая библиотека A* Pathfinding Project Выключая главный...

89