在C# 7中,我们可以使用
if (x is null) return;
字符串
而不是
if (x == null) return;
型
使用新方法(前一个例子)比使用旧方法有什么优点吗?
语义有什么不同吗?
这仅仅是口味的问题吗?如果不是,我什么时候应该用一种而不是另一种?
参考:What’s New in C# 7.0 .
在C# 7中,我们可以使用
if (x is null) return;
字符串
而不是
if (x == null) return;
型
使用新方法(前一个例子)比使用旧方法有什么优点吗?
语义有什么不同吗?
这仅仅是口味的问题吗?如果不是,我什么时候应该用一种而不是另一种?
参考:What’s New in C# 7.0 .
3条答案
按热度按时间m4pnthwp1#
**更新:**Roslyn编译器已更新,使两个运算符的行为相同 * 当没有重载相等运算符 *。请参阅当前编译器结果中的代码(代码中的
M1
和M2
),该代码显示了当没有重载相等比较器时会发生什么。它们现在都具有性能更好的==
行为。如果有重载相等比较器,代码仍然不同。有关Roslyn编译器的旧版本,请参见下面的分析。
对于
null
,它与我们在C# 6中使用的没有什么区别。然而,当你将null
更改为另一个常量时,事情变得有趣起来。举个例子:
字符串
测试结果为
a
。如果将其与通常编写的o == (object)1
进行比较,确实会产生很大的差异。is
考虑了比较另一边的类型。这很酷!我认为
== null
与is null
常量模式只是非常熟悉的“偶然”,其中is
运算符和equals运算符的语法产生相同的结果。正如svick评论的那样,
is null
调用System.Object::Equals(object, object)
,而==
调用ceq
。is
的IL:*型
==
的IL:*型
因为我们讨论的是
null
,所以这个only makes a difference on instances没有区别。当你重载了相等运算符时,这可能会改变。a64a0gku2#
重载equals运算符
当你将
null
与重载了==
操作符的类型进行比较时,这两种比较在语义上是有区别的。foo is null
将使用直接引用比较来确定结果,而foo == null
当然会运行重载的==
操作符(如果存在的话)。在这个例子中,我在重载的
==
操作符中引入了一个“bug”,导致它总是在第二个参数是null
时抛出异常:字符串
foo is null
的IL代码使用ceq
指令执行直接引用比较:型
foo == null
的IL代码使用了对重载运算符的调用:型
因此,不同之处在于,如果使用
==
,则有运行用户代码的风险(这可能会产生意外行为或性能问题)。您还可以使用SharpLab在线工具查看C#编译器如何转换
Main
方法:型
8zzbczxx3#
当你试图比较一个非空变量和一个空值时,也有一个区别。当使用
==
时,编译器会发出一个警告,而当使用is
时,编译器会发出一个错误。最有可能的是,99%的情况下,你希望编译器为这样一个基本的错误向你大喊大叫。对于is null
,+1。的数据
的
P.S.在https://dotnetfiddle.net/上使用NetCore3.1进行了测试