你的兩個較低的例子是差不多相等。但第二塊
_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