Hashtable with MultiDimensional Key in C#

后端 未结 16 1354
闹比i
闹比i 2020-11-27 02:58

I\'m basically looking for a way to access a hashtable value using a two-dimensional typed key in c#.

Eventually I would be able to do something like this



        
相关标签:
16条回答
  • 2020-11-27 03:41

    I'd suggest a slight variation on jachymko's solution which will allow you to avoid creating a class for key pairs. Instead, wrap a private dictionary of dictionaries, as so:

    public class MultiDictionary<K1, K2, V>
    {
        private Dictionary<K1, Dictionary<K2, V>> dict = 
            new Dictionary<K1, Dictionary<K2, V>>();
    
        public V this[K1 key1, K2 key2]
        {
            get
            {
                return dict[key1][key2];
            }
    
            set
            {
                if (!dict.ContainsKey(key1))
                {
                    dict[key1] = new Dictionary<K2, V>();
                }
                dict[key1][key2] = value;
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-27 03:44

    I think this might be closer to what you're looking for...

    var data = new Dictionary<int, Dictionary<bool, int>>();
    
    0 讨论(0)
  • 2020-11-27 03:44

    You need a key class for the Dictonary that implements GetHashCode correctly. And you can extend Dictonary to let you access it in a friendly way.

    The KeyPair class:

    public class KeyPair<Tkey1, Tkey2>
    {
        public KeyPair(Tkey1 key1, Tkey2 key2)
        {
            Key1 = key1;
            Key2 = key2;
        }
    
        public Tkey1 Key1 { get; set; }
        public Tkey2 Key2 { get; set; }
    
        public override int GetHashCode()
        {
            return Key1.GetHashCode() ^ Key2.GetHashCode();
        }
        public override bool Equals(object obj)
        {
            KeyPair<Tkey1, Tkey2> o = obj as KeyPair<Tkey1, Tkey2>;
            if (o == null)
                return false;
            else
                return Key1.Equals(o.Key1) && Key2.Equals(o.Key2);
        }
    }
    

    Extend Dictonary<>:

    public class KeyPairDictonary<Tkey1, Tkey2, Tvalue> 
        : Dictionary<KeyPair<Tkey1, Tkey2>, Tvalue>
    {
        public Tvalue this[Tkey1 key1, Tkey2 key2]
        {
            get
            {
                return this[new KeyPair<Tkey1, Tkey2>(key1, key2)];
            }
            set
            {
                this[new KeyPair<Tkey1, Tkey2>(key1, key2)] = value;
            }
        }
    }
    

    You can use it like this:

    KeyPairDictonary<int, bool, string> dict = 
        new KeyPairDictonary<int, bool, string>();
    
    dict[1, false] = "test";
    string test = dict[1, false];
    
    0 讨论(0)
  • 2020-11-27 03:44

    Wrap your two-dimensional key in a separate type and use that type as a key. Also consider overriding GetHashCode() and Equals() methods. Preferably use Dictionary<> instead of HashTable since apparently you can use that.

    0 讨论(0)
  • 2020-11-27 03:45

    You can do this in C# 7.0 now with the new tuples:

    // Declare
    var test = new Dictionary<(int, bool), int>();
    
    // Add
    test.Add((1, false), 5);
    
    // Get
    int a = test[(1, false)];
    
    0 讨论(0)
  • 2020-11-27 03:46

    Just in case anyone is here recently, an example of how to do this the quick and dirty way in .Net 4.0, as described by one of the commenters.

    class Program
    {
      static void Main(string[] args)
      {
         var twoDic = new Dictionary<Tuple<int, bool>, String>();
         twoDic.Add(new Tuple<int, bool>(3, true), "3 and true." );
         twoDic.Add(new Tuple<int, bool>(4, true), "4 and true." );
         twoDic.Add(new Tuple<int, bool>(3, false), "3 and false.");
    
         // Will throw exception. Item with the same key already exists.
         // twoDic.Add(new Tuple<int, bool>(3, true), "3 and true." );
    
         Console.WriteLine(twoDic[new Tuple<int, bool>(3,false)]);
         Console.WriteLine(twoDic[new Tuple<int, bool>(4,true)]);
         // Outputs "3 and false." and "4 and true."
      }
    }
    
    0 讨论(0)
提交回复
热议问题