【问题标题】:How does overloading the equality operator == really work?重载相等运算符 == 如何真正起作用?
【发布时间】:2016-01-20 15:58:24
【问题描述】:

我在MyClass中有这段代码:

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

    // Other operations to check for equality
}

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

【问题讨论】:

  • 旁注:如果 both lhs 和 rhs 都是 null 怎么办?
  • 那是因为lhs == null 不是两者都是MyClass 的对象
  • 附带说明,这是@EricLippert 关于如何正确实现运算符重载的一个很好的例子:stackoverflow.com/a/19300732/870604
  • @M.kazemAkhgary 这是有效的代码吗?铸造null?那是东西。不过,它会有用吗?

标签: c# null comparison operator-overloading equality


【解决方案1】:

编辑

我的立场是正确的。它确实递归地调用== 运算符(至少在LinqPad 4.5 中)而不是绑定到object.==。解决此问题的三种方法:

  • 如果你真的想要 value 相等语义,请重载 Equals。
  • 将lhs 和rhs 转换为object
  • 按照 MSDN 指南的建议使用 Object.ReferenceEquals

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

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

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

【讨论】:

  • 对,没错。顺便说一句,我们真的可以将null 称为object 吗?从技术上讲,null 没有任何意义。但是,我相信它有一个代表。
  • 我刚刚测试过了。在 VS 2015 中也调用递归。我误解了。感谢您提及。
【解决方案2】:

除了D Stanley回答。为了避免这种意外(Object operator == 被调用),在实现== 时使用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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-05
    相关资源
    最近更新 更多