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

本文关键字:字典 对象 列表 我可以 | 更新日期: 2023-09-27 18:36:46

// 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>();

问题:

这段代码看起来没问题吗?我知道要成为地图中的一个键,Foo需要覆盖等于和哈希代码方法 - 要么覆盖两者,要么不覆盖。

我想知道作为键的对象列表怎么样?当涉及到列表时,平等意味着什么?上面定义的地图是否安全,不会出现"对象在地图中丢失"的问题?

-卡雷普尔

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

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

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

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

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

当然,你可以,但这将是非常有限的。简单地说,一个Foo组合的列表,即使列表元素都是相同的Foo,也不一定是同一个List<Foo>。因此,您需要以某种非歧义的方式保留引用,以确保键相同,或者制作复杂的键匹配函数。

简单地使用更好的密钥类型会好得多