C# Equals和GetHashCode方法中的不一致性

C# Equals和GetHashCode方法中的不一致性,c#,.net,equals,hashcode,C#,.net,Equals,Hashcode,在阅读了这个问题后,我想进一步挖掘,并发现以下行为: 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() //fa

在阅读了这个问题后,我想进一步挖掘,并发现以下行为:

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)之间的区别与以下内容不一致: 如果两个对象不代表相同的对象引用,则 两者都不为null,它调用objA.Equals(objB)并返回结果。 这意味着如果objA重写Object.Equals(Object)方法, 这种覆盖称为

  • (3)和(5)之间的差异意味着运算符==返回true,但对象在相等方面并不相等
  • (4)、(5)、(6)和(7)之间的差异意味着两个对象在运算符==和Equals方面相等,但它们具有不同的哈希代码

  • 如果有人能解释为什么在我看来,在相当基本的.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
    确实是对称的。

    当我看到这一点时,我就是这么想的。非常感谢您了解问题的核心,尤其是从sbyte到int的隐式转换之后出现的那些“不一致性”。@pst
    a.Equals((object)b)
    当然意味着
    a.GetHashCode()==b.GetHashCode()
    。我会调用任何类型的
    ==
    行为不同于
    Equals
    break,即使.net并不严格要求这样做。(忽略隐式转换,并假设运行时类型和静态类型相同)