如何在C#中可靠地检查null值

3

如何可靠地在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 应使用objectoperator !=,因此应该可以。
  • 还有其他方法吗?

因此,在可靠性、速度、可读性方面,哪种方法最好,哪种方法最符合惯用法?Microsoft在他们的文档/编码标准/其他方面推荐任何方法吗?


在这种情况下,我认为object.ReferenceEquals(x, null)是最好的选择。 - Alessandro D'Andria
1
不在你的列表中,但我会使用(object)x != (object)null,这将强制使用在C#中预定义的重载运算符operator !=(object x, object y),它只是比较两个引用(很可能实现为两个整数“地址”,因此在幕后进行整数相等性检查)。当然,在通常情况下,您可以仅转换一侧(操作数之一),即(object)x != nullx != (object)null;编译器仍必须选择预定义的重载,而不是用户定义的重载。 - Jeppe Stig Nielsen
2个回答

3
你可以使用 System.Object 的静态 ReferenceEquals 方法。
这是技术上正确的解决方案。但是,你应该让提供该类的供应商知道它是有问题的,你不会使用它。修复他人的错误不应该成为你的责任。修复自己的错误已经足够了。

1
对于“让你的类供应商知道它是一个有缺陷的狗屎类,你不会与之合作”的说法我表示赞同。然而,我认为有一种合理的情况可以这样做:定义一个实例,其行为类似于浮点数的NaN,即它与任何东西都不相等,包括它自己(但可以争论的是,NaN的行为也是有缺陷的狗屎)。 - Suzanne Soy

2
微软建议在他们的文档/编码标准/其他方面中使用ReferenceEquals或将其转换为对象来检查空值,否则会递归调用==。这是微软的建议。此处是微软的说法。
在重载运算符"=="时常见的错误是使用(a == b),(a == null)或(b == null)来检查引用相等性。这会导致对重载的运算符"=="进行调用,从而导致无限循环。要避免循环,请使用ReferenceEquals或将类型转换为Object。
通过将其转换为对象,它意味着:
if(((object)yourObject) == null)
{}

我不是在问如何在定义“==”或“!=”运算符时测试相等性,而是在使用覆盖“==”和“!=”的类时如何测试空值。我的“!=”调用在“Main()”方法中,因此不存在任何递归调用。我将更改我的示例以使其更清晰。 - Suzanne Soy
@GeorgesDupéron - 如果(ReferenceEquals(null, y) == false){ System.Console.WriteLine(y.ToString()); } - Corak
@NoOne 你还在谈论如何在定义 operator == 时检查空值,但正如我在之前的评论中所说,我关心的是使用一个(第三方)类,该类覆盖了运算符,而不是定义运算符本身。 - Suzanne Soy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接