Building on this question, is there a simple solution for having a multi-key dictionary where either key individually can be used to identify the value?
ie.
MultikeyDictionary<TKey1, TKey2, TValue> foo;
foo.Add(key1, key2, value);
myValue = foo[key1];
// value == myValue
foo.Remove(key2);
myValue = foo[key1]; // invalid, Exception or null returned
Another simple (and effective) implementation would be to use PowerCollections'
Pair<TFirst, TSecond>
type as a dictionary key, something likePair<> implements
Equals
andGetHashCode
consistently, so you don't need to resort to multi-level dictionaries (which are more cumbersome and probably less effective).There's also a
Triple<TFirst, TSecond, TThird>
if you need a 3-key dictionary.There's nothing built into .NET BCL for this type of collection at the moment.
I see two options:
Use a two-level dictionary. The first level maps different keys to some common unique key (let's say a GUID), and the second level maps the GUID to the actual value.
Create a custom key class and implement Equals() and GetHashCode() so that any one component of the key is sufficient to find the entire key. You could then supply helper methods to construct instances of the key using only one of the values so that you could do lookups.
You may find my IndexMap implementation to be a good base for rewriting it from Java into C#. The programming model isn't as elegant as I'd prefer, but it isn't meant for developing with directly. Rather it lies behind a caching library which supplies standard annotations to allow for a succinct coding style. By using the Map interface it provides a clean compositional model when combining it with self-populating, expirational, and evictible map decorators. I am sure that someone could come up with a nice programming interface for direct usage where it is acceptable to lose the benefit of the Map interface.
I tried this and it works perfectly (include add, remove & indexer)
and even I extended it to 4 values:
Enjoy,
Ofir
This blog post seems to detail a rather decent implementation.
Yes, define a class that adds the object to an internal hashtable with both keys,