.NET’s normal Dictionary<K, T> stores one value per unique key. Most of the time that is what you want, but once in a while, a case presents itself where you’d want to store multiple values sharing the same key. For example, if you wanted to create a search index where a dictionary maps between words and the places these words occurred in text, your only choice would be to use a Dictionary<string, ICollection<Location>>.

A MultiDictionary works exactly like that, but saves you from having to check if the value collection for a key already exists, from having to remove the key only of the last value in its value collection is taken away, from having to keep count of the number of values manually and from ending up with rather inconvenient types in the GetEnumerator() and CopyTo() methods:

UML diagram of my MultiDictionary class

The IMultiDictionary<K, T> interface adds some methods on top of the IDictionary<K, T,> interface that only make sense in combination with a dictionary of collections (like the ability to remove only one item from the values collection by specifying key and value to remove).

var numberNames = new MultiDictionary<int, string>();
numberNames.Add(1, "one");
numberNames.Add(1, "eins");
numberNames.Add(2, "two");
numberNames.Add(2, "zwei");
// Determine the number of values with the specified key
int nameCount = numberNames.CountValues(1);
// Total number of entries returns 4, not just the number of collections in the dictionary
int totalCount = numerNames.Count;
// Enumerate the dictionary naturally
foreach(KeyValuePair<int, string> entry in numberNames) {
  Console.WriteLine(entry.Key.ToString() + " => " + entry.Value.ToString());

You can at any time cast the MultiDictionary<K, T> to an ICollection<KeyValuePair<K, T>> or to an ICollection<KeyValuePair<K, ICollection<T>>> and it will behave correctly.

Leave a Reply

Your email address will not be published. Required fields are marked *

Please copy the string mhPEeT to the field below: