在C#7中,我们可以使用

if (x is null) return;

而不是

if (x == null) return;

使用新方法(以前的例子)比使用旧方法有什么优势吗?

语义有什么不同吗?

这仅仅是品味的问题吗?如果没有,我应该在什么时候使用其中一个呢?

参考文献:What’s New in C# 7.0.

推荐答案

Update: Roslyn编译器已经更新,使两个运算符的行为相同when there is no overloaded equality operator.请参阅code in the current compiler results(代码中的M1M2),它显示了当没有重载的相等比较器时会发生什么.他们现在都有更好的表现.如果存在重载的相等比较器,则为the code still differs.

有关Roslyn编译器的旧版本,请参阅下面的分析.


对于null人来说,与我们习惯的C#6没有什么不同.然而,当你把null换成另一个常数时,事情就变得有趣了.

举个例子:

Test(1);

public void Test(object o)
{
    if (o is 1) Console.WriteLine("a");
    else Console.WriteLine("b");
}

测试结果为a.如果你把它和你通常写的o == (object)1相比,它确实会有很大的不同.is考虑了比较的另一边的类型.太酷了!

我认为== null vs.is null常量模式只是非常熟悉的"偶然",其中is运算符和equals运算符的语法产生相同的结果.


正如svick comments 的,is null calls System.Object::Equals(object, object) where == calls ceq.

IL for 100:

IL_0000: ldarg.1              // Load argument 1 onto the stack
IL_0001: ldnull               // Push a null reference on the stack
IL_0002: call bool [mscorlib]System.Object::Equals(object, object) // Call method indicated on the stack with arguments
IL_0007: ret                  // Return from method, possibly with a value

IL for 100:

IL_0000: ldarg.1              // Load argument 1 onto the stack
IL_0001: ldnull               // Push a null reference on the stack
IL_0002: ceq                  // Push 1 (of type int32) if value1 equals value2, else push 0
IL_0004: ret                  // Return from method, possibly with a value

因为我们说的是null,所以和这only makes a difference on instances没有区别.当重载相等运算符时,这可能会发生变化.

.net相关问答推荐

实体框架核心:Azure容器应用程序的执行超时已过期

使用PowerShell在Windows容器内安装exe

正则表达式匹配 URL 中的多个子目录

如何在 C# 中自动删除临时文件?

线程安全性的单元测试?

您如何确定两个 HashSet 是否相等(按值,而不是按引用)?

设置日志(log)文件名以在 Log4j 中包含当前日期

每第 N 个字符/数字拆分一个字符串/数字?

BackgroundWorker 中未处理的异常

如何在 WPF 中创建/制作圆角按钮?

.net 自定义配置如何不区分大小写解析枚举 ConfigurationProperty

如何异步 Files.ReadAllLines 并等待结果?

如何在多个解决方案之间共享相同的 Resharper 设置,无需人工干预?

为什么发布和调试模式下的代码行为不同?

在 WPF DataGrid 中绑定 ComboBoxColumn 的 ItemsSource

从 'System.Int32' 到 'System.Nullable`1[[System.Int32, mscorlib]] 的无效转换

如何在 C# 中处理 XML

IronPython 与 Python .NET

C# 相当于 Java 的 Exception.printStackTrace()?

在构建事件命令行中放置注释的正确方法?