关于c#:如果在覆盖Equals()时未能覆盖GetHashCode(),会出现什么问题?

What can go wrong if one fails to override GetHashCode() when overriding Equals()?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Why is it important to override GetHashCode when Equals method is overridden?

在C中,如果在重写equals()时未能重写getHashCode(),具体会发生什么错误?


最明显的方法是映射结构。

当用作字典或哈希表的键时,执行此操作的任何类都将具有不可预测的行为。原因是实现同时使用gethashcode和equals在表中正确查找值。算法的简短版本如下

  • 取hashcode的模数乘以bucket的个数,这就是bucket索引。
  • 为指定的键和特定bucket中的每个键调用.equals()。
  • 如果有匹配值,则no match=no value。
  • 未能保持gethashcode和equals的同步将完全破坏该算法(以及许多其他算法)。


    把哈希/字典结构想象成一个编号桶的集合。如果您总是将内容放入与getHashCode()对应的bucket中,那么您只需搜索一个bucket(使用equals())即可查看其中是否有内容。如果你找对了,这就行了。

    所以规则是:如果equals()表示两个对象是equal(),那么它们必须具有相同的getHashCode()。


    任何使用该键的算法都将无法工作,假设它依赖于哈希键的预期行为。

    Equal的两个对象应该具有相同的哈希键值,默认实现无法远程保证该值。


    如果不重写GetHashCode,任何比较对象的操作都可能出错。

    如文件所述,如果两个实例相等,GetHashCode必须返回相同的值,那么任何希望测试它们是否相等的代码都有权使用GetHashCode作为第一个传递给可能相等的组对象(因为它知道具有不同哈希代码的对象不可能相等)。如果您的GetHashCode方法为相同的对象返回不同的值,那么它们在第一遍中可能会进入不同的组,并且永远不会使用它们的Equals方法进行比较。

    这可能会影响到任何收集类型的数据结构,但在基于哈希代码的数据结构(如字典和哈希集)中,这会特别有问题。

    简而言之:当您重写Equals时,总是重写GetHashCode,并确保它们的实现是一致的。