x是null和ReferenceEquals(x,null)之间有区别吗?

时间:2018-02-23 10:10:36

标签: c#

当我写这篇文章时:

ReferenceEquals(x, null)

Visual Studio建议

  

null check可以简化。

并将其简化为

x is null

那些真的一样吗?

4 个答案:

答案 0 :(得分:7)

我注意到很多答案,指出x == nullx is nullReferenceEquals(x, null)都是等效的-在大多数情况下,这是对的。但是,在某些情况下,您不能使用x == null,如下所述:

请注意,以下代码假定您已为类实现了Equals方法:

请勿执行此操作-递归调用操作符==方法,直到发生堆栈溢出:

public static bool operator ==(MyClass x1, MyClass x2)
{
   if (x1 == null)
      return x2 == null;

   return x1.Equals(x2)
}

执行此操作:

public static bool operator ==(MyClass x1, MyClass x2)
{
   if (x1 is null)
      return x2 is null;

   return x1.Equals(x2)
}

public static bool operator ==(MyClass x1, MyClass x2)
{
   if (ReferenceEquals(x1, null))
      return ReferenceEquals(x2, null);

   return x1.Equals(x2)
}

答案 1 :(得分:3)

  

那些真的一样吗?

语义上是(假设x不是值类型)。您正在对所有引用类型执行空检查。

实施:没有。 x == nullx is null将直接作为IL指令实施,但Object.ReferenceEquals(x, null)将是方法调用。 1

另请注意,如果x的类型已被覆盖operator ==,那么x == null可能不等效(在运算符重载中更改空值检查的语义充其量只是代码不佳,因为没有人期望这样的语义变化。)

1 当然,优化者可以识别出这个并输出IL,你需要查看IL以确认这一点。

答案 2 :(得分:1)

我意识到我很喜欢参加聚会,并且已经给出了答案,但是我觉得有必要总结一下,因为这是我每8-12个月左右要搜索一次的事情,希望有一个我能理解的解释(希望能得到发布)。

1。 ReferenceEquals(a,b)

这是一种经过实践检验的方法,可以执行安全的引用相等性比较。它基本上执行(object)a == (object)b(或类似的操作),并且具有可以立即识别其使用且不能覆盖的优点。


2。 a == b

这种方法对大多数人来说是“自然的”(因为在整个C#中完成的大多数比较都将使用此运算符完成)。

引用类型的默认行为应正确。但是,这可能会过载,从而导致意外结果(想象操作员过载的执行失败)。

就像@mdebeus所说的那样,另外的风险(尽管对于阅读C#底漆的胜任的猴子来说还是很小的)正在引起StackOverflowException。当重载==和!=并使用方法本身内部的运算符时,会出现这种情况。


3。 a是b

好的,这是我们得到的一种闪亮的含糖新事物。 Microsoft在这种情况下描述 is

  

is运算符检查表达式结果的运行时类型是否与给定类型兼容。

     

[...]

     

如果E的结果为非null并且E的T表达式返回true   可以通过参考转换(拳击)转换为T型   转换或拆箱转换;否则,它返回false。   is运算符不考虑用户定义的转换。

(阅读完整的说明here

简而言之,如果可以通过装箱,拆箱或协方差通过b转换a,则它将返回true。 如您所料,这对null效果很好。


总而言之,作为个人说明,尽管使等式重载中的空检查变得更短,更漂亮,但我认为我仍然会使用ReferenceEquals,这仅仅是因为我是一个控件-freak,至少有一部分 的工作方式使我担心协方差情况。

答案 3 :(得分:0)

在这种情况下他们的意思相同,是的。大多数人会使用x == null

我猜ReferenceEquals可能有点令人困惑,因为实际上null是一个文字,意味着根本没有参考。任何引用如何等于无引用

请注意,x is null仅适用于C#7且pattern matching feature。通常,您使用is检查x是否为兼容类型,但null不是类型。所以这也有点令人困惑。

这就是我更喜欢x == null

的原因