![](/img/trans.png)
[英]How can I overload the “==” operator to determine of two ID numbers are the same?
[英]overload == (and != , of course) operator, can I bypass == to determine whether the object is null
当我尝试在C#中重载operator ==和!=并按推荐重写Equal时,我发现我无法区分普通对象和null。 例如,我定义了一个类Complex。
public static bool operator ==(Complex lhs, Complex rhs)
{
return lhs.Equals(rhs);
}
public static bool operator !=(Complex lhs, Complex rhs)
{
return !lhs.Equals(rhs);
}
public override bool Equals(object obj)
{
if (obj is Complex)
{
return (((Complex)obj).Real == this.Real &&
((Complex)obj).Imaginary == this.Imaginary);
}
else
{
return false;
}
}
但是当我想用的时候
if (temp == null)
当temp真的为null时,会发生一些异常。 并且我不能使用==来确定lhs是否为null,这将导致无限循环。
在这种情况下我该怎么办
我能想到的一种方法是给我们一些像Class.Equal(对象,对象)(如果它存在的话)在我做检查时绕过==。
解决问题的正常方法是什么?
谢谢。
您可以在等于覆盖的顶部使用以下内容:
if (Object.ReferenceEquals(obj, null))
return false;
您获得的异常可能是StackOverflowException,因为您的==运算符将导致无限递归。
编辑:
如果Complex是一个结构,那么NullReferenceExceptions不应该有任何问题。 如果Complex是一个类,你可以改变你的==和!=运算符重载的实现来避免异常(Laurent Etiemble已经在他的回答中指出了这一点):
public static bool operator ==(Complex lhs, Complex rhs)
{
return Equals(lhs, rhs);
}
public static bool operator !=(Complex lhs, Complex rhs)
{
return !Equals(lhs, rhs);
}
您应该考虑在运算符重载中使用静态Equals方法(它将调用实例Equals方法):
public static bool operator ==(Complex lhs, Complex rhs)
{
return Equals(lhs, rhs);
}
public static bool operator !=(Complex lhs, Complex rhs)
{
return !Equals(lhs, rhs);
}
注意:您也可以在Equals方法中检查null
。
您还可以在MSDN上阅读Object.Equals主题 ,这是一个很好的样本来源。
public static bool operator ==(Complex lhs, Complex rhs)
{
if (Object.ReferenceEquals(lhs, null))
{
return Object.ReferenceEquals(rhs, null);
}
return lhs.Equals(rhs);
}
public static bool operator !=(Complex lhs, Complex rhs)
{
return !(lhs == rhs);
}
穷人的单元测试
Action<Complex, Complex> tester = (left, right) =>
{
Console.WriteLine(left == right);
Console.WriteLine(left != right);
Console.WriteLine(left == null);
Console.WriteLine(left != null);
Console.WriteLine("---");
};
tester(new Complex(), new Complex());
tester(null, new Complex());
tester(null, null);
tester(new Complex(), null);
有一个更好的方法,然后使用运营商is
和cast
:
Complex c = obj as Complex;
return (c != null) && (c.Real == this.Real) && (c.Imaginary == this.Imaginary);
这是一个关于Equals
运算符覆盖和与null
比较的快速测试:
class Complex
{
public override bool Equals(object obj)
{
if (obj is Complex)
{
return true;
}
else
{
return false;
}
}
}
调试不会进入操作员的身体:
var b = (new Complex() == new Complex());
我想你应该在==运算符实现中测试null。 否则,当lhs为null时,你会调用Complex(null).Equals(我不知道C#,但在Java中这将是一个Nullpointer异常)
要测试null,我建议像:
if (null == lhs && null == rhs) return true
else if (null == lhs) return false
else return lhs.Equals(rhs);
因此,将为上面的所有==比较调用Object.Equals。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.