At one point during my application I came across the need to have three string keys for an instance of a class (I am using C# 3.5, so I couldn't use a tuple). By looking online, I came across this answer whose code I used: https://stackoverflow.com/a/15804355/5090537
After tailoring its bits and pieces for my needs, in the end my custom class looked like this:
public class MultiKeyDictionary<K1, K2, K3, V> : Dictionary<K1, MultiKeyDictionary<K2, K3, V>> { public V this[K1 key1, K2 key2, K3 key3] { get { return ContainsKey(key1) ? this[key1][key2, key3] : default(V); } set { if (!ContainsKey(key1)) this[key1] = new MultiKeyDictionary<K2, K3, V>(); this[key1][key2, key3] = value; } } public bool ContainsKey(K1 key1, K2 key2, K3 key3) { return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3); } public void Add(K1 key1, K2 key2, K3 key3, V value) { if (!ContainsKey(key1)) this[key1] = new MultiKeyDictionary<K2, K3, V>(); if (!this[key1].ContainsKey(key2, key3)) this[key1][key2] = new Dictionary<K3, V>(); this[key1][key2][key3] = value; } } This worked great for my needs but I have a few questions on this data structure:
1) Since I am actually inheriting from a Dictionary(K1, Dictionary(K2, V)), is it correct to assume that GetHashCode is implemented for me and I don't need to specify a separate implementation? And the same for Equals?
2) Is also the premise that I needed to create my own custom class correct? Since I couldn't use a string array or string list for example, because then there would be a ReferenceEquals comparison instead of the memberwise comparison that I needed (key1 equal to key1, key2 equal to key2, and key3 equal to key3)?
Dictionary<Tuple<string,string,string>,YourClass>a straight forward solution or you can useList<Tuple<string,string,string,YourClass>>alsoTupleclass is not available prior to C# 4.Tuple; and use that struct as the key in a one-dimensionalDictionary.