即便沒有空檢查,使用「as」而不是強制轉換是否有意義? [關閉]

在開發博客,在線代碼示例和(最近)甚至是一本書中,我一直在尋找像這樣的代碼: 多線程

var y = x as T;
y.SomeMethod();

或者更糟糕的是: 優化

(x as T).SomeMethod();

這對我來講沒有意義。 若是您肯定xT類型,則應使用直接強制轉換: (T)x 。 若是您不肯定,可使用as但須要在執行某些操做以前檢查null 。 以上代碼所作的就是將(有用的) InvalidCastException爲(無用的) NullReferenceExceptionthis

我是惟一一個認爲這是對as關鍵字的公然濫用的人嗎? 仍是我錯過了一些明顯的東西,上面的模式實際上有意義? spa


#1樓

你的理解是真的。 這聽起來像是試圖對我進行微觀優化。 當您肯定類型時,應該使用普通的強制轉換。 除了產生更明智的例外,它也會快速失敗。 若是你對類型的假設錯了,你的程序將當即失敗,你將可以當即看到失敗的緣由,而不是等待NullReferenceExceptionArgumentNullException ,甚至在未來的某個時候等待邏輯錯誤。 在通常狀況下, as表達式,表示後面沒有null支票的地方是一個代碼味道。 線程

另外一方面,若是您不肯定轉換並指望它失敗,您應該使用as而不是使用try-catch塊包裝的普通轉換。 此外,建議使用as類型檢查,而後進行強制轉換。 代替: code

if (x is SomeType)
   ((SomeType)x).SomeMethod();

它爲is關鍵字生成一個isinst指令 ,併爲一個cast(有效地執行兩次轉換)的castclass指令 ,你應該使用: 對象

var v = x as SomeType;
if (v != null)
    v.SomeMethod();

這隻會生成一個isinst指令。 前一種方法在多線程應用中的潛在缺陷的競爭條件可能致使要改變的變量的類型後is勾選成功,並在投行失敗。 後一種方法不容易出現這種錯誤。 開發


建議不要在生產代碼中使用如下解決方案。 若是你真的討厭C#中這樣一個基本的構造,你能夠考慮切換到VB或其餘語言。 get

若是一我的極度討厭強制轉換語法,他/她能夠編寫一個擴展方法來模仿強制轉換: 博客

public static T To<T>(this object o) { // Name it as you like: As, Cast, To, ...
    return (T)o;
}

並使用整潔的[?]語法:

obj.To<SomeType>().SomeMethod()

#2樓

恕我直言, as剛剛有意義當與聯合null檢查:

var y = x as T;
if (y != null)
    y.SomeMethod();

#3樓

直接投射比as關鍵字須要一對括號。 所以,即便在您100%肯定類型是什麼的狀況下,它也能夠減小視覺混亂。

可是就異常事項達成了一致意見。 但至少對我來講,最用途as歸結爲檢查null以後,我以爲這比捕獲異常漂亮。


#4樓

當我使用「as」時,99%的時間是我不肯定實際對象類型是何時

var x = obj as T;
if(x != null){
 //x was type T!
}

而且我不想捕獲顯式的強制轉換異常,也不想使用「is」進行兩次強制轉換:

//I don't like this
if(obj is T){
  var x = (T)obj; 
}

#5樓

我相信as關鍵字能夠被認爲是來自C ++的dynamic_cast的更優雅的版本。

相關文章
相關標籤/搜索