如何在没有无限递归的情况下检查'=='运算符重载中的空值?
时间:2020-03-05 18:56:20 来源:igfitidea点击:
以下将导致==运算符重载方法的无限递归
Foo foo1 = null; Foo foo2 = new Foo(); Assert.IsFalse(foo1 == foo2); public static bool operator ==(Foo foo1, Foo foo2) { if (foo1 == null) return foo2 == null; return foo1.Equals(foo2); }
如何检查空值?
解决方案
回答
在重载方法中强制转换为对象:
public static bool operator ==(Foo foo1, Foo foo2) { if ((object) foo1 == null) return (object) foo2 == null; return foo1.Equals(foo2); }
回答
使用ReferenceEquals
:
Foo foo1 = null; Foo foo2 = new Foo(); Assert.IsFalse(foo1 == foo2); public static bool operator ==(Foo foo1, Foo foo2) { if (object.ReferenceEquals(null, foo1)) return object.ReferenceEquals(null, foo2); return foo1.Equals(foo2); }
回答
试试Object.ReferenceEquals(foo1,null)
无论如何,我不建议重载==
操作符。它应该用于比较引用,并使用"等于"进行"语义"比较。
回答
使用ReferenceEquals
。从MSDN论坛:
public static bool operator ==(Foo foo1, Foo foo2) { if (ReferenceEquals(foo1, null)) return ReferenceEquals(foo2, null); if (ReferenceEquals(foo2, null)) return false; return foo1.field1 == foo2.field2; }
回答
我们可以尝试使用对象属性并捕获生成的NullReferenceException。如果我们尝试的属性是从Object继承或者覆盖的,则此方法适用于任何类。
public static bool operator ==(Foo foo1, Foo foo2) { // check if the left parameter is null bool LeftNull = false; try { Type temp = a_left.GetType(); } catch { LeftNull = true; } // check if the right parameter is null bool RightNull = false; try { Type temp = a_right.GetType(); } catch { RightNull = true; } // null checking results if (LeftNull && RightNull) return true; else if (LeftNull || RightNull) return false; else return foo1.field1 == foo2.field2; }
回答
如果我已经覆盖了bool Equals(object obj)
并且希望运算符==
和Foo.Equals(object obj)
返回相同的答案,我通常会实现!=
运算符,如下所示:
public static bool operator ==(Foo foo1, Foo foo2) { return object.Equals(foo1, foo2); } public static bool operator !=(Foo foo1, Foo foo2) { return !object.Equals(foo1, foo2); }
然后,运算符==
将在为我完成所有空检查之后最终调用foo1.Equals(foo2)
,如果两者相等,我将重写它们以进行实际检查。