Archive

Posts Tagged ‘Dictionary’

Creating Multi-key Dictionary object

Dictionary object has many different uses, and since .Net 2.0 the generic support makes it more common. The biggest limitation of the classic Dictionary<TKey, TValue> is that it has only one key. If you need more than one key, you need to look how to customize it.

Maybe a List<T>?

My first thought was about generic List<T>. Suppose I want to use only string values, I can create the Dictionary<List<String>,String> so I can manage the keys in a list like this:

var listDictionary = new Dictionary<List<string>, string>();

But this code has one big limitation. Take a look:

listDictionary.Add(new List<string>
{
"Key1","Key2"
}, "val");
listDictionary.Add(new List<string>
{
"Key1","Key2"
}, "val");
Console.WriteLine("Exception should be thrown already...");

When the Add() method is looking for matching elements in the keys collection to prevent duplicate key, he can’t find that two keys are equal. It’s the same when you trying to call Equal() on a list:

var l1 = new List<string> { "A" };
var l2 = new List<string> { "A" };
Console.WriteLine(l1.Equals(l2));
//Output: False

This is why we should use in such cases the method SequenceEqual:

var l1 = new List<string> { "A" };
var l2 = new List<string> { "A" };
Console.WriteLine(l1.SequenceEqual(l2));
//Output: True

I can always create an extension method and “override” the Add() and ContainsKey() methods, but of course this is not my first choice.

Custom Class

Another option is creating custom class with property for each key. Same as List<T>, it won’t work because it’s a reference type, and by adding new instance of this class we’re taking a risk to add existing key to the collection (and hence,  not getting the correct value when we want it back).

Tuple

In .Net 4.0 Microsoft introduced the Tuple class, which simply  allow creating object with variety of typed fields. The main goal of that object (at least, for our needs) that it’s act like an immutable type – you cannot changed it after it’s first created. For that reason the  default Equals() method will return true for two different instances of the Tuple class with the same values, not like the List<T> type. Creating the “Tupled” Dictionary for the sample above will look like this:

var tupleDictionary = new Dictionary<Tuple<string, string>, string>();

tupleDictionary.Add(new Tuple<string, string>("key1", "key2"), "val");
//When adding this item exception will be thrown as expected
tupleDictionary.Add(new Tuple<string, string>("key1", "key2"), "val");

Now, you can safely call the Add() and ContainsKey() method.

Categories: C# Tags: , , ,
%d bloggers like this: