繁体   English   中英

Null 条件运算符和 void 方法

[英]Null conditional operator and void methods

在 C# 6 之前,我会编写代码来处理如下对象:

if (_odbcConnection != null)
{
    _odbcConnection.Close();
    _odbcConnection.Dispose();
    _odbcConnection = null;
}

有了 6,我可以写更少的代码:

_odbcConnection?.Close();
_odbcConnection?.Dispose();
_odbcConnection = null;

但两者是等价的吗?

你的两个较低的例子几乎相等。 但是第二块

_odbcConnection?.Close();
_odbcConnection?.Dispose();
_odbcConnection = null;

将被编译器翻译成类似的东西

var tmp1 = _odbcConnection;
if (tmp1 != null) tmp1.Close();
var tmp2 = _odbcConnection;
if (tmp2 != null) tmp2.Dispose();
_odbcConnection = null;

这意味着这个版本是线程安全的,而第一个(带有外部if子句)不是。 如果某个神秘线程在if之后但在Close()Dispose()之前将_odbcConnection设置为null ,则会抛出NullReferenceException

通过使用空条件运算符可以避免这个问题,因为引用首先存储在编译器生成的变量中,然后进行检查和使用。


以上翻译仅适用于字段和属性。 对于局部变量(仅在单个方法的范围内,例如方法参数),这种翻译是没有必要的,代码最终像

if (_odbcConnection != null) _odbcConnection.Dispose();

那是因为局部变量不能被不同的线程改变。

当然,这只是生成的 C#。 在 IL 中,您可能不会再看到它,因为它要么被优化掉了,要么已经过时了,因为在 IL 中,参考值被加载到寄存器中,然后进行比较。 同样,另一个线程不能再更改寄存器中的值。 所以在 IL 级别上,这个讨论有点毫无意义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM