.NET dictionary with two keys and one value

前端 未结 13 3020
盖世英雄少女心
盖世英雄少女心 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:32

    Maybe, something like this:

    public class TwoKeyDictionary
    {
        private object m_data_lock = new object();
        private Dictionary m_dic1 = new Dictionary();
        private Dictionary m_dic2 = new Dictionary();
    
        public void AddValue(Tkey1 key1, Tkey2 key2, TValue value)
        {
            lock(m_data_lock)
            {
                m_dic1[key1] = key2;
                m_dic2[key2] = value;
            }
        }
    
        public TValue getByKey1(Tkey1 key1)
        {
            lock(m_data_lock)
                return m_dic2[m_dic1[key1]];
        }
    
        public TValue getByKey2(Tkey key2)
        {
            lock(m_data_lock)
                return m_dic2[key2];
        }
    
        public void removeByKey1(Tkey1 key1)
        {
            lock(m_data_lock)
            {
                Tkey2 tmp_key2 =   m_dic1[key1];
                m_dic1.Remove(key1);
                m_dic2.Remove(tmp_key2);
            }
        }
    
        public void removeByKey2(Tkey2 key2)
        {
            lock(m_data_lock)
            {
                Tkey1 tmp_key1 = m_dic1.First((kvp) => kvp.Value.Equals(key2)).Key;
                m_dic1.Remove(tmp_key1);
                m_dic2.Remove(key2);
            }
        }
    }
    

    I can offer a second solution, but it seems more slow and ugly vs. the first.

    public class TwoKeysDictionary
    {
        private class TwoKeysValue
        {
            public K1 Key1 { get; set; }
            public K2 Key2 { get; set; }
            public V Value { get; set; }
        }
    
        private List> m_list = new List>();
    
        public void Add(K1 key1, K2 key2, V value)
        {
            lock (m_list)
                m_list.Add(new TwoKeysValue() { Key1 = key1, Key2 = key2, Value = value });
        }
    
        public V getByKey1(K1 key1)
        {
            lock (m_list)
                return m_list.First((tkv) => tkv.Key1.Equals(key1)).Value;
        }
    
        public V getByKey2(K2 key2)
        {
            lock (m_list)
                return m_list.First((tkv) => tkv.Key2.Equals(key2)).Value;
        }
    
        public void removeByKey1(K1 key1)
        {
            lock (m_list)
                m_list.Remove(m_list.First((tkv) => tkv.Key1.Equals(key1)));
        }
    
        public void removeByKey2(K2 key2)
        {
            lock (m_list)
                m_list.Remove(m_list.First((tkv) => tkv.Key2.Equals(key2)));
        }
    }
    

    In very bad case, when Keys are a big structures (i.e. big value-types) and Keys are equals by size, and values are small value-types (for instance, a byte), with first solution you had: one set of Key1 , two sets of Key2, one set of values = 3 sets of big objects and 1 set of small values. With second solution you had: one set of Key1 , one set of Key2, one set of values = 2 sets of big objects and small set with values. I.e. with using of first solution you need by 50% (or by lower) more memory space vs. second, but a second solution is a very, very slow vs. first.

提交回复
热议问题