Equals和GetHashCode方法不一致

emp*_*mpi 12 .net c# equals hashcode

读完这个问题后为什么"int"和"sbyte"GetHashCode函数生成不同的值?我想进一步挖掘并发现以下行为:

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)
Run Code Online (Sandbox Code Playgroud)
  1. (3)和(4)之间的差异打破了Equals应该是对称的要求.
  2. (2)和(4)之间的差异与MSDN规范不一致,即:

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

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

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

Cod*_*aos 15

你的问题是你错过了隐式转换i.Equals(j).它过载了int.Equals(int).在这里,我们比较i(int)j,这是一回事.发生相同的隐式转换==.

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

Equals是对称的,但你的调用代码不是.如果你用i.Equals((object)j)它来抑制隐式转换,它将返回false,表明它Equals确实是对称的.