在開發博客,在線代碼示例和(最近)甚至是一本書中,我一直在尋找像這樣的代碼: 多線程
var y = x as T; y.SomeMethod();
或者更糟糕的是: 優化
(x as T).SomeMethod();
這對我來講沒有意義。 若是您肯定x
是T
類型,則應使用直接強制轉換: (T)x
。 若是您不肯定,可使用as
但須要在執行某些操做以前檢查null
。 以上代碼所作的就是將(有用的) InvalidCastException
爲(無用的) NullReferenceException
。 this
我是惟一一個認爲這是對as
關鍵字的公然濫用的人嗎? 仍是我錯過了一些明顯的東西,上面的模式實際上有意義? spa
你的理解是真的。 這聽起來像是試圖對我進行微觀優化。 當您肯定類型時,應該使用普通的強制轉換。 除了產生更明智的例外,它也會快速失敗。 若是你對類型的假設錯了,你的程序將當即失敗,你將可以當即看到失敗的緣由,而不是等待NullReferenceException
或ArgumentNullException
,甚至在未來的某個時候等待邏輯錯誤。 在通常狀況下, 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()
恕我直言, as
剛剛有意義當與聯合null
檢查:
var y = x as T; if (y != null) y.SomeMethod();
直接投射比as
關鍵字須要一對括號。 所以,即便在您100%肯定類型是什麼的狀況下,它也能夠減小視覺混亂。
可是就異常事項達成了一致意見。 但至少對我來講,最用途as
歸結爲檢查null
以後,我以爲這比捕獲異常漂亮。
當我使用「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; }
我相信as
關鍵字能夠被認爲是來自C ++的dynamic_cast
的更優雅的版本。