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