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

时间:2012-06-11 21:07:00

标签: c#

// 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方法 - 覆盖两者或不覆盖。

我想知道对象列表作为键是什么?当涉及到List时,平等意味着什么?上面定义的地图是否安全于“物体丢失在地图中”问题?

-Karephul

3 个答案:

答案 0 :(得分:5)

仅当您使用原始List<T>个实例作为键时,此功能才会生效 如果您使用相同的项目创建新的List<T>,则不会将其视为相同的密钥,因为List<T>不会覆盖Equals()GetHashCode()

换句话说,它将使用引用相等。

如果您想更改它,可以写一个IEqualityComparer<List<T>>

答案 1 :(得分:3)

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

答案 2 :(得分:0)

当然,你可以,但那将是 令人难以置信的 有限。简而言之,Foo的组合列表,即使列表元素都相同Foo,也不一定是List<Foo>。因此,您需要以一些非模糊的方式保留引用,以确保键是相同的,或者创建一个复杂的键匹配函数。

只需使用更好的密钥类型就可以了,