重载相等运算符 == 如何真正起作用?
How does overloading the equality operator == really work?
我在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
比较如何工作?
编辑
我的意思是正确的。它 递归调用 ==
运算符(至少在 LinqPad 4.5 中)而不是绑定到 object.==
。可以通过三种方法解决此问题:
- 如果您确实需要 value 等式语义,请改用
Equals
。
- 将
lhs
和 rhs
转换为 object
- 按照 MSDN 指南的建议使用
Object.ReferenceEquals
I suppose that comparison itself will invoke the overload function again
否 - null
不是 MyClass
,因此调用使用 ==
的默认含义,即引用相等。
另请注意,guidelines for overloading ==
声明它只应为不可变类型重载,因为 ==
的预期行为是引用相等性,这是默认情况下发生的情况。 Equals
意味着 "value equality" 语义。
除了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
}
我在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
比较如何工作?
编辑
我的意思是正确的。它 递归调用 ==
运算符(至少在 LinqPad 4.5 中)而不是绑定到 object.==
。可以通过三种方法解决此问题:
- 如果您确实需要 value 等式语义,请改用
Equals
。 - 将
lhs
和rhs
转换为object
- 按照 MSDN 指南的建议使用
Object.ReferenceEquals
I suppose that comparison itself will invoke the overload function again
否 - null
不是 MyClass
,因此调用使用 ==
的默认含义,即引用相等。
另请注意,guidelines for overloading ==
声明它只应为不可变类型重载,因为 ==
的预期行为是引用相等性,这是默认情况下发生的情况。 Equals
意味着 "value equality" 语义。
除了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
}