Equals和GetHashCode方法不一致

时间:2012-09-19 20:43:38

标签: c# .net equals hashcode

在阅读了这个问题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)
  1. (3)和(4)之间的差异打破了Equals应该是对称的要求。
  2. (2)和(4)之间的区别与MSDN specification不一致,表示:
      

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

  3. (3)和(5)之间的差异意味着operator ==返回true,但是对象在Equals方面不相等。
  4. (4),(5),(6)和(7)之间的差异意味着两个对象在operator ==和Equals方面是相等的,但它们具有不同的哈希码。
  5. 我很感兴趣,如果有人能够解释为什么我认为在相当基本的.NET类型中会出现不一致的行为。

1 个答案:

答案 0 :(得分: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确实是对称的。