首页 文章

Equals和GetHashCode方法不一致

提问于
浏览
12

在阅读了这个问题之后Why do "int" and "sbyte" GetHashCode functions generate different values?我想进一步挖掘并发现以下行为:

sbyte i = 1;            
int j = 1;
object.Equals(i, j) //false (1)
object.Equals(j, i) //false (2) 
i.Equals(j) //false (3)
j.Equals(i) //true (4)
i == j //true (5)
j == i //true (6)
i.GetHashCode() == j.GetHashCode() //false (7)
  • (3)和(4)之间的差异打破了Equals应该是对称的要求 .

  • (2)和(4)之间的差异与MSDN specification不一致,即:

如果两个对象不表示相同的对象引用且都不为null,则调用objA.Equals(objB)并返回结果 . 这意味着如果objA重写Object.Equals(Object)方法,则调用此覆盖 .

  • (3)和(5)之间的差异意味着operator ==返回true,但是对象在Equals方面不相等 .

  • (4),(5),(6)和(7)之间的差异意味着两个对象在operator ==和Equals方面是相等的,但是它们具有不同的哈希码 .

我很感兴趣,如果有人能解释为什么我认为在相当基本的.NET类型中观察到不一致的行为 .

1 回答

  • 15

    您的问题是您错过了 i.Equals(j) 中的隐式转换 . 它转到了重载 int.Equals(int) . 在这里你要比较 i(int)j ,它们是相同的 . == 发生了相同的隐式转换 .

    其他比较适用于 intsbyte ,根据定义,它们是不同的 . j.Equals(i) 转到重载 int.Equals(object) ,因为参数不能隐式转换为 sbyte .

    Equals 对于它们是对称的,但您的调用代码不是 . 如果使用 i.Equals((object)j) 禁止隐式转换,它将返回 false ,表明 Equals 确实是对称的 .

相关问题