阅读这个问题
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)之间的差异打破了等于对称的要求.
>(2)和(4)之间的区别与MSDN specification不一致:
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)之间的区别意味着两个对象在operator ==和Equals方面相等,但是它们具有不同的哈希码.
我非常感兴趣,如果有人可以解释为什么在我看来,在相当基本的.NET类型中观察到不一致的行为.
解决方法
你的问题是你错过了i.Equals(j)中的隐式转换.它去重载int.Equals(int).在这里你要比较我和(int)j,这是同样的事情.相同的隐式转换发生在==.
其他比较工作在一个int和一个sbyte,根据定义是不同的. j.Equals(i)转到重载int.Equals(object),因为参数不是隐式转换为sbyte.
等于它们是对称的,但是你的呼叫代码不是.如果使用i.Equals((object)j)抑制隐式转换,它将返回false,表明Equals确实是对称的.