.NET dictionary with two keys and one value

前端 未结 13 2951
盖世英雄少女心
盖世英雄少女心 2020-12-14 00:23

Is there a dictionary available in .NET that could hold 2 keys and one value. Like

Dictionary(Of TKey, Of TKey, TValue)

I have

相关标签:
13条回答
  • 2020-12-14 00:50

    Here's something better in terms of efficiency.

    public class MultiKeyDictionary<TKeyType1, TKeyType2, TValueType>
    {
        private readonly object threadLock = new object();
        private readonly Dictionary<TKeyType1, TValueType> _dictionary1 = new Dictionary<TKeyType1, TValueType>();
        private readonly Dictionary<TKeyType2, TValueType> _dictionary2 = new Dictionary<TKeyType2, TValueType>();
        private readonly Dictionary<TKeyType1, TKeyType2> _Key1Key2Map = new Dictionary<TKeyType1, TKeyType2>();
        private readonly Dictionary<TKeyType2, TKeyType1> _Key2Key1Map = new Dictionary<TKeyType2, TKeyType1>();
    
        public bool Add(TKeyType1 key1, TKeyType2 key2, TValueType v)
        {
            if (ContainsKey1(key1) || ContainsKey2(key2))
                return false;
            _dictionary1.Add(key1, v);
            _dictionary2.Add(key2, v);
            _Key1Key2Map.Add(key1, key2);
            _Key2Key1Map.Add(key2, key1);
            return true;
        }
        public bool ContainsKey1(TKeyType1 key)
        {
            return _dictionary1.ContainsKey(key);
        }
        public bool ContainsKey2(TKeyType2 key)
        {
            return _dictionary2.ContainsKey(key);
        }       
        //Note if TKeyType1 and TKeyType2 are the same then we are forced to use GetBy functions
        public TValueType GetByKey1(TKeyType1 key)
        {
            return _dictionary1[key];
        }
        public TValueType GetByKey2(TKeyType2 key)
        {
            return _dictionary2[key];
        }
        public bool SetByKey1(TKeyType1 key, TValueType val)
        {
            if (ContainsKey1(key))
                return false;
            lock (threadLock)
            {
                var key2 = _Key1Key2Map[key];
                _dictionary1[key] = val;
                _dictionary2[key2] = val;
            }
            return true;
        }
        public bool SetByKey2(TKeyType2 key, TValueType val)
        {
            if (ContainsKey2(key))
                return false;
            lock (threadLock)
            {
                var key1 = _Key2Key1Map[key];
                _dictionary1[key1] = val;
                _dictionary2[key] = val;
            }
            return true;
        }
        public void RemoveUsingKey1(TKeyType1 key)
        {
            lock (threadLock)
            {
                var key2 = _Key1Key2Map[key];
                _dictionary1.Remove(key);
                _dictionary2.Remove(key2);
                _Key1Key2Map.Remove(key);
                _Key2Key1Map.Remove(key2);
            }
        }
        public void RemoveUsingKey2(TKeyType2 key)
        {
            lock (threadLock)
            {
                var key1 = _Key2Key1Map[key];
                _dictionary1.Remove(key1);
                _dictionary2.Remove(key);
                _Key1Key2Map.Remove(key1);
                _Key2Key1Map.Remove(key);
            }
        }
        public bool Contains(TKeyType1 key)
        {
            return _dictionary1.ContainsKey(key);
        }
        public bool Contains(TKeyType2 key)
        {
            return _dictionary2.ContainsKey(key);
        }
        public TValueType this[TKeyType1 key]
        {
            get => GetByKey1(key);
            set => SetByKey1(key, value);
        }
        public TValueType this[TKeyType2 key]
        {
            get => GetByKey2(key);
            set => SetByKey2(key, value);
        }
        public void Remove(TKeyType1 key)
        {
            RemoveUsingKey1(key);
        }
        public void Remove(TKeyType2 key)
        {
            RemoveUsingKey2(key);
        }
        public int Count => _dictionary1.Count;
        public Dictionary<TKeyType1, TValueType>.KeyCollection Key1s => _dictionary1.Keys;
        public Dictionary<TKeyType2, TValueType>.KeyCollection Key2s => _dictionary2.Keys;
        public Dictionary<TKeyType1, TValueType>.ValueCollection Values => _dictionary1.Values;
        public void Clear()
        {
            lock (threadLock)
            {
                _dictionary1.Clear();
                _dictionary2.Clear();
                _Key1Key2Map.Clear();
                _Key2Key1Map.Clear();
            }
        }
        //Map between Keys
        public TKeyType2 Key2(TKeyType1 key)
        {
            return _Key1Key2Map[key];
        }
        public TKeyType1 Key1(TKeyType2 key)
        {
            return _Key2Key1Map[key];
        }
    }
    
    0 讨论(0)
提交回复
热议问题