簡體   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