来自Microsoft new-features-in-c-7-0:
public void PrintStars(object o)
{
if (o is null) return; // constant pattern "null"
if (!(o is int i)) return; // type pattern "int i"
WriteLine(new string('*', i));
}
o == null
和o is null
的差异是什么?
答案 0 :(得分:10)
o is null
已翻译为object.Equals(null, o)
(您可以看到here)。
object.Equals
代码is written as:
public static bool Equals(Object objA, Object objB)
{
if (objA == objB)
{
return true;
}
if (objA == null || objB == null)
{
return false;
}
return objA.Equals(objB);
}
所以最后会有一个o == null
(第一个if
)。请注意,System.Object
未定义operator==
,因此使用的是引用相等的引用类型。
理论上,通过观察被叫代码,可以认为o == null
(o
一个System.Object
)应该比o is null
更快(操作更少)......但谁知道呢? : - )
最终结果是,通过两条不同的路线o is null
和o == null
(o
一个System.Object
)会返回相同的结果。
通过查看,我们甚至可以看到o == null
与object.ReferenceEquals(o, null)
相同(o
和System.Object
): - )。
有趣的问题应该是,为什么C#编译器不会将x is null
转换为object.ReferenceEquals(x, null)
?。请注意,由于可以使用可空类型的装箱,它甚至可以用于:
int? a = null;
if (a is null) { /* */ }
对编译器的更改使此响应无效...如果您点击“此处”链接即可看到
答案 1 :(得分:1)
由于@xanatos的答案已经过时了(但这仅在最后提到),我正在写一个新的,因为我也想知道这一点并对其进行研究。
简而言之::如果您不重载==
运算符,则o == null
和o is null
是相同的。
如果您确实使==
运算符重载,则o == null
将调用它,但是o is null
不会。
o is null
始终与ReferenceEquals(o, null)
相同,即,它仅仅检查该值是否为null,不调用任何运算符或Equals
方法
更长的答案: here is a SharpLab sample展示了各种检查null的方法。
如果以IL形式查看结果,则会看到:
is null
和ReferenceEquals
产生相同的代码o == null
将调用重载的operator==
object.Eqauls(o, null)
调用该方法operator==
中对C
进行注释,您将看到o == null
现在产生与o is null
相同的代码答案 2 :(得分:-2)
"之间的差异是"和==是"是"特殊的是,当你比较对象的类型和类型时,如果你比较它并作为typeof(类型),它就作为==。