[英]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.