Reputation: 4665
I'm working with legacy code and I see a dictionary whose key is a list of objects...
var myCrazyDictionary = new Dictionary<List<MyKeyObject>, List<MyValueObject>>();
How does such a dictionary behave? You know, because of reference types...
Is it working magically like so?
// ????
myCrazyDictionary.Add(new List<MyKeyObject> { new MyKeyObject { Key1 = "1", Key2 = 2 } }, new List<MyValueObject> { new MyValueObject { Value = "!" } });
// ???????????
var result = myCrazyDictionary[new List<MyKeyObject> { new MyKeyObject { Key1 = "1", Key2 = 2 } }];
// Will this hold the value: "!" or crash or something else?
var byWhatBlackMagic = result[0].Value;
Upvotes: 2
Views: 87
Reputation: 127563
It will be have the same as if you did a dictionary Dictionary<Object, List<MyValueObject>>
and just did a new Object()
for both the add and retrieval. List<T>
does not override Equals(object)
and GetHashCode()
so it just uses the default behavior which only compares object references. It will not look inside of the list to compare. So your example will throw a KeyNotFoundException
when you try to do myCrazyDictionary[new List<MyKeyObject> { ... }]
because you are creating a "new object" and that new object is not in the dictionary (because you just created it).
You can get the functionality you want, you just need to make a custom IEqualityComparer<List<MyKeyObject>>
and pass it in to the constructor of your dictionary.
Be aware! If you do make a custom comparer nothing in your List<MyKeyObject>
that is associated with your custom Equals(List<MyKeyObject>, List<MyKeyObject>)
nor your custom .GetHashCode(List<MyKeyObject>)
can be changed while it is acting as the roll of a key or you will break the internal logic of Dictionary
.
Upvotes: 7