我被一个看似简单的问题难住了。我有两个要与 != 进行比较的对象。
当我运行应用程序时, a != b 为真。当我设置断点并执行 Watch 时,a.GetHashCode() == b.GetHashCode() 为真。
这两个(引用类型)对象是在不同的程序集中定义的,但是我找不到对 != 方法的覆盖(尽管 GetHashCode 已被覆盖)。对此还有其他解释吗?两个对象的 GetHashCode 是否可能相同,但未覆盖的 != 会返回 true?
谢谢。
当两个不同的对象返回相同的代码时,称为“冲突”。只有大约 40 亿个可能的整数值,以及超过 40 亿个 [your class name here] 可能的值,一些冲突是不可避免的。这就是为什么基于散列的结构(即Dictionary
)不能完全依赖GetHashCode
,它还需要一个合理的Equals
实现才能有效。该Equals
方法用于解决这些冲突。
当然,类的创建者也有可能覆盖GetHashCode
或Equals
在某种程度上犯了一个错误,在某种程度上违反了生成哈希码的“合同”。 以下GetHashCode
是创建方法时要牢记的准则列表。请记住,您必须做的事情相当少,而另一组事情可以做以使其有效地工作。
return 0;
实际上是一个完全可以接受的GetHashCode
实现。它符合所有规则,它有 100% 的几率引起碰撞,所以它会非常低效,你不应该真的这样做。
两个不相等的对象具有相同的哈希码是完全合法的,但对于两个相等的对象具有不同的哈希码是无效的。
Dictionary 样式集合类使用 hashcode 值(从指定为键的对象返回的 GetHashCode 值)将键/值对放入 hashbin。键的哈希码值相同的所有键/值对进入相同的哈希箱。如果哈希码生成有效,则意味着字典中每个非空哈希箱中的键/值对将非常少(希望只有一个)。
当您通过指定一个对象作为键来访问字典中的内容时,查找要返回的正确值的伪逻辑是:
与在 List 样式集合中查找对象相比(当哈希码分布良好时),这就是字典查找非常有效的原因。