【问题标题】:Inconsistency in Equals and GetHashCode methodsEquals 和 GetHashCode 方法不一致
【发布时间】:2012-09-19 20:43:38
【问题描述】:

在阅读了这个问题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)
  1. (3) 和 (4) 之间的差异打破了 Equals 应该是对称的要求。
  2. (2) 和 (4) 之间的差异与 MSDN specification 不一致,上面写着:

    如果两个对象不代表同一个对象引用并且 两者都不为空,它调用 objA.Equals(objB) 并返回结果。 这意味着如果 objA 覆盖 Object.Equals(Object) 方法, 调用此覆盖。

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

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

【问题讨论】:

  • 这就是我看到它时的想法。非常感谢您看到问题的核心 empi
  • 所有这些“不一致”都源于从 sbyte 到 int 的隐式转换。
  • @pst a.Equals((object)b) 当然暗示a.GetHashCode()==b.GetHashCode()。我会称任何==Equals 行为不同的类型都已损坏,即使.net 并不严格要求这样做。 (忽略隐式转换,假设运行时类型和静态类型相同)

标签: c# .net equals hashcode


【解决方案1】:

您的问题是您错过了i.Equals(j) 中的隐式转换。它转到过载int.Equals(int)。在这里,您正在比较 i(int)j,它们是相同的。 == 发生相同的隐式转换。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-03
    • 2012-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多