如何在C#中可靠地检查空值,包括何时重载运算符==
和!=
?
class MyClass
{
public static bool operator ==(MyClass a, MyClass b) { return false; }
public static bool operator !=(MyClass a, MyClass b) { return true; }
}
class Program {
static void Main(string[] args) {
MyClass x = new MyClass();
MyClass y = null;
if (x != null) { System.Console.WriteLine(x.ToString()); }
// Next line throws a NullReferenceException
if (y != null) { System.Console.WriteLine(y.ToString()); }
}
}
我知道有以下选项可供选择:
x != null
重载运算符时不可靠。null != x
重载运算符时不可靠。(x ?? null) != null
类型仍为MyClass
,因此在重载运算符时不可靠。object.ReferenceEquals(x, null)
应该没问题。x.Equals(null)
无效(当然,因为我们在x
上调用方法,可以是null
)object o = x; o != null
应使用object
的{{1}},因此它应该有用。那么,哪种方法在可靠性,速度,可读性方面最好,哪种方法最具惯用性? Microsoft是否会在其文档/编码标准/其他方面推荐任何方法?
答案 0 :(得分:3)
您可以使用System.Object的静态ReferenceEquals方法。
这是技术上正确的解决方案。然而,你应该做的是让你的班级供应商知道这是一个错误的狗屎,你不会使用它。修复其他人的错误不应该是你的责任。这足以修复自己的错误。
答案 1 :(得分:2)
Microsoft是否会在其文档/编码标准/其他方面推荐任何方法?
是Microsoft确实建议,ReferenceEquals
或在检查null之前强制转换为object。否则==
将被递归调用。 This是微软必须说的。
operator ==的重载中的常见错误是使用(a == b),(a == null)或(b == null)来检查引用相等性。这反而导致调用重载的运算符==,导致无限循环。使用ReferenceEquals或将类型转换为Object,以避免循环。
通过强制转换为对象意味着,
if(((object)yourObject) == null)
{}