当我写下这句话:
ReferenceEquals(x, null)
Visual Studio建议可以简化空值检查,并将其简化为:
x is null
这两个是否真的相同?
当我写下这句话:
ReferenceEquals(x, null)
x is null
这两个是否真的相同?
我注意到很多答案都指出 x == null
, x is null
, 和 ReferenceEquals(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)
}
==
,只要通过将操作数强制转换为object
来强制执行默认的object ==
比较。 - Jeff Mercado这种方法对大多数人来说感觉“自然”(因为在C#中进行的大多数比较都将使用此运算符)。
引用类型的默认行为应该是正确的。但是,这可以被重载,这可能会导致意外的结果(想象一下运算符重载的失败实现)。
正如@mdebeus所说,另一个风险(即使是对于已阅读C#入门指南的熟练猴子而言也是微不足道的)是导致StackOverflowException
。当重载==和!=并在方法内部使用运算符时,这可能会出现。
好的,这是一种闪亮新颖的甜蜜物品。Microsoft在这种情况下用is来描述:
is运算符检查表达式结果的运行时类型是否与给定类型兼容。
[...]
E is T表达式返回true,如果E的结果非空并且可以通过引用转换、装箱转换或拆箱转换将其转换为类型T;否则,它返回false。is运算符不考虑用户定义的转换。
(阅读完整描述此处)
简而言之,如果a可以通过装箱、拆箱或协变转换为b,则将返回true。正如您所期望的那样,这对null非常有效。
x is null
是可行的?根据 MSDN:“[is] 检查对象是否与给定类型兼容”。null
是一种类型吗? - Michael Haddad== null
而不是is null
的原因;-) - Tim Schmelter
ReferenceEquals
只是调用了return a == b
- 请参见源代码,因此超常见的x == null
也同样有效。 - Rhumborlx
的类型没有重载operator==
时才会。ReferenceEquals
永远不会触发该重载(因为它在静态类型为“object”的值上运行),但是如果您自己在代码中编写==
,那么很可能会发生这种情况。 - Jeroen MostertReferenceEquals
只是调用a == b
。然而,由于它接受object
类型的参数,ReferenceEquals(x,null)
并不等同于x == null
,而是等同于((object)x) == ((object)null)
。 - relatively_random