简体   繁体   English

Equals和GetHashCode方法不一致

[英]Inconsistency in Equals and GetHashCode methods

After reading this question Why do "int" and "sbyte" GetHashCode functions generate different values? 读完这个问题后为什么“int”和“sbyte”GetHashCode函数生成不同的值? I wanted to dig further and found following behavior: 我想进一步挖掘并发现以下行为:

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. Difference between (3) and (4) breaks the requirement that Equals should be symmetric. (3)和(4)之间的差异打破了Equals应该是对称的要求。
  2. Difference between (2) and (4) is not coherent with MSDN specification that says: (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. 如果两个对象不表示相同的对象引用且都不为null,则它调用objA.Equals(objB)并返回结果。 This means that if objA overrides the Object.Equals(Object) method, this override is called. 这意味着如果objA重写Object.Equals(Object)方法,则调用此覆盖。

  3. Difference between (3) and (5) means that operator == returns true, however objects are not equal in terms of Equals. (3)和(5)之间的差异意味着operator ==返回true,但是对象在Equals方面不相等。
  4. Difference between (4), (5), (6) and (7) means that two objects are equal in terms of operator == and Equals, however they have different hash codes. (4),(5),(6)和(7)之间的差异意味着两个对象在operator ==和Equals方面是相等的,但它们具有不同的哈希码。

I'm very interested if anyone can explain why such in my opinion inconsistent behaviour is observed in rather fundamental .NET types. 我很感兴趣,如果有人能解释为什么我认为在相当基本的.NET类型中观察到不一致的行为。

Your problem is that you missed the implicit conversion in i.Equals(j) . 你的问题是你错过了i.Equals(j)的隐式转换。 It goes to the overload int.Equals(int) . 它转到了重载int.Equals(int) Here you're comparing i and (int)j , which are the same thing. 在这里你要比较i(int)j ,它们是相同的。 The same implicit conversion happens for == . 对于==会发生相同的隐式转换。

The other comparisons work on an int and a sbyte , which by definition are different. 其他比较适用于intsbyte ,根据定义,它们是不同的。 j.Equals(i) goes to the overload int.Equals(object) , because the argument isn't implicitly convertible to sbyte . j.Equals(i)转到重载int.Equals(object) ,因为参数不能隐式转换为sbyte

Equals is symmetric for them, but your calling code isn't. Equals它们是对称的,但你的调用代码不是。 If you suppress the implicit conversion with i.Equals((object)j) , it'll return false , showing that Equals is indeed symmetric. 如果使用i.Equals((object)j)抑制隐式转换,它将返回false ,表明Equals确实是对称的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM