关于c#:Equals和GetHashCode方法不一致

Inconsistency in Equals and GetHashCode methods

在阅读了这个问题之后,"int"和"sbyte"gethashcode函数为什么生成不同的值?我想进一步挖掘,发现以下行为:

1
2
3
4
5
6
7
8
9
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)之间的差异打破了等号应该是对称的要求。
  • (2)和(4)之间的差异与MSDN规范不一致,后者表示:

    If the two objects do not represent the same object reference and
    neither is null, it calls objA.Equals(objB) and returns the result.
    This means that if objA overrides the Object.Equals(Object) method,
    this override is called.

  • (3)和(5)之间的差异意味着operator==返回true,但是对象不等于equals。
  • (4)、(5)、(6)和(7)之间的差异意味着两个对象在运算符==和等于方面是相等的,但是它们有不同的哈希代码。
  • 我很感兴趣,如果有人能解释为什么在我看来,在相当基础的.NET类型中观察到不一致的行为。


    你的问题是你错过了i.Equals(j)中的隐式转换。它进入过载int.Equals(int)。这里你比较的是i(int)j,它们是一样的。同样的隐式转换也发生在==上。

    其他的比较工作是在一个int和一个sbyte上进行的,两者的定义不同。j.Equals(i)进入重载int.Equals(object),因为该参数不能隐式转换为sbyte

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