C# 我可以使用对象列表作为字典键吗? //不需要重写。。让CLR处理equal和hashcode。 类Foo{public Name{get;set;}公共地址{get;set;}} 字典映射=新字典();

C# 我可以使用对象列表作为字典键吗? //不需要重写。。让CLR处理equal和hashcode。 类Foo{public Name{get;set;}公共地址{get;set;}} 字典映射=新字典();,c#,C#,问题: 这个代码看起来还好吗?我理解,要成为映射中的一个键,Foo需要重写equals和hashcode方法——要么重写两者,要么不重写 我想知道作为键的对象列表是什么?在列表中,平等意味着什么?上面定义的地图是否安全,不会出现“地图中丢失的对象”问题 -Karephul仅当您使用原始的列表实例作为键时,此操作才有效。 如果使用相同的项创建新的列表,它将不会被视为相同的键,因为List不会覆盖Equals()和GetHashCode() 换句话说,它将使用引用等式 如果你想改变这一点,你可以写一

问题:

这个代码看起来还好吗?我理解,要成为映射中的一个键,Foo需要重写equals和hashcode方法——要么重写两者,要么不重写

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


-Karephul

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

换句话说,它将使用引用等式

如果你想改变这一点,你可以写一个
IEqualityComparer

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

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

List a=新列表(1,2,3);
// 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>();
列表b=新列表(1、2、3)//不同于 字典>地图=新字典>(); map.Add(a,a.Sum()); int aSum=map[b]//KeyNotFoundException,因为这是另一个实例。 HashSet a=新的HashSet(1,2,3); HashSet b=新的HashSet(1,2,3)//不同于 字典>地图1=新字典>(); map1.Add(a,a.Sum()); int aSum=map1[b]//KeyNotFoundException,因为这是另一个实例。 HashSet a=新的HashSet(1,2,3); HashSet b=新的HashSet(1,2,3)//不同于 字典>地图2=新字典> (HashSet.CreateSetComparer())//未使用实例比较-相等集相等 添加(a,a.Sum()); int aSum=map2[b]//6.
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