【Unity】Unity中将字典序列化

发布于:2025-05-20 ⋅ 阅读:(12) ⋅ 点赞:(0)

Unity中将字典序列化,在预制体上能够看到字典的内容,也可以直接在预制体上拖拽给字典赋值

直接上代码

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class SerializableDic
{
}

[Serializable]
public class SerializableDic<TKey, TValue> :
    SerializableDic,
    ISerializationCallbackReceiver,
    IDictionary<TKey, TValue>


{
    [SerializeField] private List<SerializableKeyValuePair> list = new List<SerializableKeyValuePair>();

    [Serializable]
    private struct SerializableKeyValuePair
    {
        public TKey Key;
        public TValue Value;


        public SerializableKeyValuePair(TKey key, TValue value)
        {
            Key = key;
            Value = value;
        }
    }



    #region key index

    private Dictionary<TKey, int> KeyPositions
    {
        get { return _keyPositions.Value; }
    }

    private Lazy<Dictionary<TKey, int>> _keyPositions;


    public SerializableDic()
    {
        _keyPositions = new Lazy<Dictionary<TKey, int>>(MakeKeyPositions);
    }

    #endregion



    private Dictionary<TKey, int> MakeKeyPositions()
    {
        Dictionary<TKey, int> dictionary = new Dictionary<TKey, int>(list.Count);
        for (var i = 0; i < list.Count; i++)
        {
            dictionary[list[i].Key] = i;
        }

        return dictionary;
    }


    public void OnBeforeSerialize()
    {
    }


    public void OnAfterDeserialize()
    {
        _keyPositions = new Lazy<Dictionary<TKey, int>>(MakeKeyPositions);
    }



    #region IDictionary<TKey, TValue>

    /// <summary>
    ///  array[index]   dic[key]
    /// </summary>
    /// <param name="key"></param>
    public TValue this[TKey key]
    {
        get => list[KeyPositions[key]].Value;
        set
        {
            SerializableKeyValuePair pair = new SerializableKeyValuePair(key, value);
            if (KeyPositions.ContainsKey(key))
            {
                list[KeyPositions[key]] = pair;
            }
            else
            {
                KeyPositions[key] = list.Count;
                list.Add(pair);
            }
        }
    }

    public ICollection<TKey> Keys
    {
        get { return list.Select(tuple => tuple.Key).ToArray(); }
    }

    public ICollection<TValue> Values
    {
        get { return list.Select(tuple => tuple.Value).ToArray(); }
    }


    public void Add(TKey key, TValue value)
    {
        if (KeyPositions.ContainsKey(key))
            throw new ArgumentException("An element with the same key already exists in the dictionary.");
        else
        {
            KeyPositions[key] = list.Count;
            list.Add(new SerializableKeyValuePair(key, value));
        }
    }


    public bool ContainsKey(TKey key)
    {
        return KeyPositions.ContainsKey(key);
    }


    public bool Remove(TKey key)
    {
        if (KeyPositions.TryGetValue(key, out var index))
        {
            KeyPositions.Remove(key);

            list.RemoveAt(index);
            for (var i = index; i < list.Count; i++)
                KeyPositions[list[i].Key] = i;

            return true;
        }
        else
            return false;
    }


    public bool TryGetValue(TKey key, out TValue value)
    {
        if (KeyPositions.TryGetValue(key, out var index))
        {
            value = list[index].Value;
            return true;
        }
        else
        {
            value = default;
            return false;
        }
    }

    #endregion



    #region ICollection <KeyValuePair<TKey, TValue>>

    public int Count
    {
        get { return list.Count; }
    }

    public bool IsReadOnly
    {
        get { return false; }
    }


    public void Add(KeyValuePair<TKey, TValue> kvp)
    {
        Add(kvp.Key, kvp.Value);
    }


    public void Clear()
    {
        list.Clear();
    }


    public bool Contains(KeyValuePair<TKey, TValue> kvp)
    {
        return KeyPositions.ContainsKey(kvp.Key);
    }


    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
    {
        var numKeys = list.Count;
        if (array.Length - arrayIndex < numKeys)
            throw new ArgumentException("arrayIndex");
        for (var i = 0; i < numKeys; i++, arrayIndex++)
        {
            var entry = list[i];
            array[arrayIndex] = new KeyValuePair<TKey, TValue>(entry.Key, entry.Value);
        }
    }


    public bool Remove(KeyValuePair<TKey, TValue> kvp)
    {
        return Remove(kvp.Key);
    }

    #endregion



    #region IEnumerable <KeyValuePair<TKey, TValue>>

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
        return list.Select(ToKeyValuePair).GetEnumerator();


    }

    static KeyValuePair<TKey, TValue> ToKeyValuePair(SerializableKeyValuePair skvp)
    {
        return new KeyValuePair<TKey, TValue>(skvp.Key, skvp.Value);
    }


    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    #endregion
}

直接将该类替换为原字典类Dictionary即可!


网站公告

今日签到

点亮在社区的每一天
去签到