可能重复:为什么在重写Equals方法时重写GetHashCode很重要?
在C#中,如果在覆盖Equals()时未能覆盖GetHashCode(),那么具体可能出现什么问题?
最明显的方法是映射结构 .
当用作Dictionary或HashTable的Key时,执行此操作的任何类都将具有不可预测的行为 . 原因是该实现使用GetHashCode和Equals来正确地在表中查找值 . 该算法的简短版本如下
将HashCode的模数乘以桶的数量,这是桶索引
为指定的Key和特定存储桶中的每个Key调用.Equals() .
如果匹配的值是值,则不匹配=无值 .
未能使GetHashCode和Equals保持同步将完全破坏此算法(以及许多其他算法) .
将哈希/字典结构视为编号桶的集合 . 如果你总是把东西放在与他们的GetHashCode()对应的桶中,那么你只需要搜索一个桶(使用Equals())来查看是否存在某些东西 . 如果你正在寻找正确的桶,这是有效的 .
所以规则是:如果Equals()说两个对象是Equal(),它们必须具有相同的GetHashCode() .
如果您没有覆盖 GetHashCode ,那么比较您的对象的任何内容都可能会出错 .
GetHashCode
正如记录的那样 GetHashCode 必须返回相同的值,如果两个实例相等,那么它是任何代码的特权,它们希望测试它们的相等性,使用 GetHashCode 作为第一遍来分组可能相等的对象(因为它知道)具有不同哈希码的对象不能相等) . 如果 GetHashCode 方法为相等对象返回不同的值,那么它们可能会在第一遍中进入不同的组,并且永远不会使用它们的 Equals 方法进行比较 .
Equals
这可能会影响任何集合类型的数据结构,但在基于哈希代码的数据结构(例如字典和散列集)中会特别成问题 .
简而言之:当您覆盖 Equals 时,始终覆盖 GetHashCode ,并确保它们的实现是一致的 .
任何使用Key的算法都将无法工作,假设它依赖于散列键的预期行为 .
两个 Equal 对象应该具有相同的哈希键值,默认实现不能保证远程保证 .
Equal
4 回答
最明显的方法是映射结构 .
当用作Dictionary或HashTable的Key时,执行此操作的任何类都将具有不可预测的行为 . 原因是该实现使用GetHashCode和Equals来正确地在表中查找值 . 该算法的简短版本如下
将HashCode的模数乘以桶的数量,这是桶索引
为指定的Key和特定存储桶中的每个Key调用.Equals() .
如果匹配的值是值,则不匹配=无值 .
未能使GetHashCode和Equals保持同步将完全破坏此算法(以及许多其他算法) .
将哈希/字典结构视为编号桶的集合 . 如果你总是把东西放在与他们的GetHashCode()对应的桶中,那么你只需要搜索一个桶(使用Equals())来查看是否存在某些东西 . 如果你正在寻找正确的桶,这是有效的 .
所以规则是:如果Equals()说两个对象是Equal(),它们必须具有相同的GetHashCode() .
如果您没有覆盖
GetHashCode
,那么比较您的对象的任何内容都可能会出错 .正如记录的那样
GetHashCode
必须返回相同的值,如果两个实例相等,那么它是任何代码的特权,它们希望测试它们的相等性,使用GetHashCode
作为第一遍来分组可能相等的对象(因为它知道)具有不同哈希码的对象不能相等) . 如果GetHashCode
方法为相等对象返回不同的值,那么它们可能会在第一遍中进入不同的组,并且永远不会使用它们的Equals
方法进行比较 .这可能会影响任何集合类型的数据结构,但在基于哈希代码的数据结构(例如字典和散列集)中会特别成问题 .
简而言之:当您覆盖
Equals
时,始终覆盖GetHashCode
,并确保它们的实现是一致的 .任何使用Key的算法都将无法工作,假设它依赖于散列键的预期行为 .
两个
Equal
对象应该具有相同的哈希键值,默认实现不能保证远程保证 .