重载等于运算符==如何真正起作用?

时间:2015-10-21 15:10:19

标签: c# null comparison operator-overloading equality

我在MyClass中有这段代码:

public static bool operator ==(MyClass lhs, MyClass rhs)
{
    if (lhs == null || rhs == null)
        return false;

    // Other operations to check for equality
}

在代码的第一行,我将lhsrhsnull进行比较。我不确定,但我想比较本身会再次调用重载函数。然后我们又回到那条线上,它会调用自己,等等。一种无限递归。
但我们都知道不会发生。在我看来,这意味着与null比较不会调用相等重载。那真的发生了什么?如何与null进行比较?

2 个答案:

答案 0 :(得分:5)

修改

我的立场得到了纠正。它 以递归方式调用==运算符(至少在LinqPad 4.5中),而不是绑定到object.==。有三种方法可以解决这个问题:

  • 如果您真的想要 value 等式语义,请改为重载Equals
  • lhsrhs投放到object
  • 使用Object.ReferenceEquals作为MSDN指南推荐
  

我认为比较本身会再次调用重载函数

否 - null不是MyClass,因此调用使用==的默认含义,即引用相等。

还要注意guidelines for overloading ==表示只应为不可变类型重载它,因为==的预期行为是引用相等,这是默认情况下发生的。 Equals暗示“值相等”语义。

答案 1 :(得分:2)

除了 D Stanley 的答案。为了避免这种类型的挑战(Object运算符==被调用),在实施Object.ReferenceEquals时使用==

public static bool operator ==(MyClass lhs, MyClass rhs)   
{
    // lhs and rhs are the same instance (both are null included)
    if (Object.ReferenceEquals(lhs, rhs))
      return true;
    else if (Object.ReferenceEquals(lhs, null) || Object.ReferenceEquals(rhs, null))
      return false;

    // From here we have different instances, none of them is null
    // Other operations to check for equality
}