【发布时间】:2019-08-30 21:31:58
【问题描述】:
我编写了一个简单的类来包装 XElement。我想将相等操作传递给包装的实例。所以我写了这个:
public class XmlWrapper
{
protected readonly XElement _element;
public XmlWrapper(XElement element)
{
_element = element;
}
static public bool operator == (XmlWrapper lhs, XmlWrapper rhs)
{
return lhs._element.Equals(rhs._element);
}
static public bool operator != (XmlWrapper lhs, XmlWrapper rhs)
{
return !(lhs == rhs);
}
}
这看起来很简单,但实际上它会为非常简单的空检查抛出异常:
XmlWrapper wrapper = new XmlWrapper(someElement);
XmlWrapper nullWrapper = null;
if (wrapper != nullWrapper) Console.WriteLine("Wrapper is not null"); //This line throws
这是因为相等运算符为其参数之一接收 null,因此无法检索包装的 XElement。所以显而易见的想法是添加一个空检查,如下所示:
static public bool operator == (XmlWrapper lhs, XmlWrapper rhs)
{
if (lhs == null && rhs == null) return true;
if (lhs == null || rhs == null) return false;
return lhs._element.Equals(rhs._element);
}
但是,这会导致无限递归,因为== 运算符再次调用== 运算符。
如果这是任何其他类型的方法,我只会调用基础,但这不适用于运算符,例如你不会写
if (lhs base.== rhs)
那么我该如何解决这个问题?有没有办法从重载的操作符体内调用基本的== 操作符?或者在不使用==的情况下执行空检查的其他方式?
【问题讨论】:
-
检查
ReferenceEquals(null, lhs) -
理想情况下你应该覆盖
Equals方法 -
提供了完整答案here
-
请注意,完整的答案在 FM "Guidelines for Overriding Equals() and Operator ==" 中提供,特别是:“如果两者都为 null,或者两者都是相同的实例,则返回 true。如果一个为 null,但不是两者,则返回 false。 "
if (System.Object.ReferenceEquals(a, b)) ...
标签: c# .net operator-overloading