你的两个较低的例子是差不多相等。但第二块
_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级别上,这个讨论有点毫无意义。
运行您已经编写并自行查看的代码。 – Servy