我可以使用对象列表作为字典键吗?
问题描述:
// 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
答
如果您使用原始List<T>
实例作为密钥这只会工作。
如果使用相同的项目创建新的List<T>
,则不会将其视为相同的密钥,因为List<T>
不会覆盖Equals()
和GetHashCode()
。
换句话说,它将使用引用相等。如果你想改变它,你可以写IEqualityComparer<List<T>>
。
+0
+ 1为好的答案。例如 – karephul
答
当然,你可能,但是这将是难以置信有限。简而言之,即使列表元素都是相同的Foo
,组合列表Foo
也不一定是相同的List<Foo>
。因此,您需要以某些非模糊的方式来保持引用,以确保密钥相同,或者制作复杂的密钥匹配功能。
它会很远,远更好地简单地使用更好的密钥类型。
+ 1 – karephul