首页 文章

如果在重写Equals()时未能覆盖GetHashCode(),会出现什么问题? [重复]

提问于
浏览
16

可能重复:为什么在重写Equals方法时重写GetHashCode很重要?

在C#中,如果在覆盖Equals()时未能覆盖GetHashCode(),那么具体可能出现什么问题?

4 回答

  • 0

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

    当用作Dictionary或HashTable的Key时,执行此操作的任何类都将具有不可预测的行为 . 原因是该实现使用GetHashCode和Equals来正确地在表中查找值 . 该算法的简短版本如下

    • 将HashCode的模数乘以桶的数量,这是桶索引

    • 为指定的Key和特定存储桶中的每个Key调用.Equals() .

    • 如果匹配的值是值,则不匹配=无值 .

    未能使GetHashCode和Equals保持同步将完全破坏此算法(以及许多其他算法) .

  • 8

    将哈希/字典结构视为编号桶的集合 . 如果你总是把东西放在与他们的GetHashCode()对应的桶中,那么你只需要搜索一个桶(使用Equals())来查看是否存在某些东西 . 如果你正在寻找正确的桶,这是有效的 .

    所以规则是:如果Equals()说两个对象是Equal(),它们必须具有相同的GetHashCode() .

  • 0

    如果您没有覆盖 GetHashCode ,那么比较您的对象的任何内容都可能会出错 .

    正如记录的那样 GetHashCode 必须返回相同的值,如果两个实例相等,那么它是任何代码的特权,它们希望测试它们的相等性,使用 GetHashCode 作为第一遍来分组可能相等的对象(因为它知道)具有不同哈希码的对象不能相等) . 如果 GetHashCode 方法为相等对象返回不同的值,那么它们可能会在第一遍中进入不同的组,并且永远不会使用它们的 Equals 方法进行比较 .

    这可能会影响任何集合类型的数据结构,但在基于哈希代码的数据结构(例如字典和散列集)中会特别成问题 .

    简而言之:当您覆盖 Equals 时,始终覆盖 GetHashCode ,并确保它们的实现是一致的 .

  • 1

    任何使用Key的算法都将无法工作,假设它依赖于散列键的预期行为 .

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

相关问题