我可以使用对象列表作为字典键吗?

问题描述:

// No overrides required .. let CLR take care of equal and hashcode. 
Class Foo {public Name{get; set;} public Address{get; set;}} 

Dictionary<List<Foo>, int> map = new Dictionary<List<Foo>, int>(); 

问:我可以使用对象列表作为字典键吗?

这段代码看看好吗?我知道要成为Map中的一个键,Foo需要重写equals和hashcode方法 - 要么覆盖两者,要么都不覆盖。

我想知道如何将对象列表作为键?在列表中,平等意味着什么?上面定义的地图是否可以避免“对象迷失地图”问题?

-Karephul

List<int> a = new List<int>(1, 2, 3); 
List<int> b = new List<int>(1, 2, 3); //different instance than a 

Dictionary<List<int>, int>> map = new Dictionary<List<int>, int>>(); 
map.Add(a, a.Sum()); 
int aSum = map[b]; //KeyNotFoundException because this is a different instance. 


HashSet<int> a = new HashSet<int>(1, 2, 3); 
HashSet<int> b = new HashSet<int>(1, 2, 3); //different instance than a 

Dictionary<HashSet<int>, int>> map1 = new Dictionary<HashSet<int>, int>>(); 
map1.Add(a, a.Sum()); 
int aSum = map1[b]; //KeyNotFoundException because this is a different instance. 


HashSet<int> a = new HashSet<int>(1, 2, 3); 
HashSet<int> b = new HashSet<int>(1, 2, 3); //different instance than a 

Dictionary<HashSet<int>, int>> map2 = new Dictionary<HashSet<int>, int>> 
    (HashSet<int>.CreateSetComparer()); //instance comparison not used - equal sets are equal 
map2.Add(a, a.Sum()); 
int aSum = map2[b]; //6 
+0

+ 1 – karephul

如果您使用原始List<T>实例作为密钥这只会工作。
如果使用相同的项目创建新的List<T>,则不会将其视为相同的密钥,因为List<T>不会覆盖Equals()GetHashCode()

换句话说,它将使用引用相等。如果你想改变它,你可以写IEqualityComparer<List<T>>

+0

+ 1为好的答案。例如 – karephul

当然,你可能,但是这将是难以置信有限。简而言之,即使列表元素都是相同的Foo,组合列表Foo也不一定是相同的List<Foo>。因此,您需要以某些非模糊的方式来保持引用,以确保密钥相同,或者制作复杂的密钥匹配功能。

它会很远,更好地简单地使用更好的密钥类型。