首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Effective C# 原則 3:優先使用 is 或 as 運算子,避免強制轉型(五)

     編輯:關於C語言

foreach 迴圈與強制轉型的風險

foreach 為了同時支援實值型別與參考型別轉換,必須使用強制轉型。這使得 foreach 對任何目標物件都表現一致,但也因此可能拋出 InvalidCastException 例外。

IEnumerator.Current 的型別限制

IEnumerator.Current 回傳 System.Object,該物件未覆寫轉換運算子,故無法滿足我們先前的測試條件。(譯註:若集合儲存 SecondType,却用 MyType 進行 foreach,轉換會失敗,因迴圈中取得的是 System.Object,轉換行為等同 MyType t = (MyType)o;,此處 o 為 SecondType 但以 System.Object 形式存在。)

強制轉型的檢查機制

使用強制轉型的 foreach 不會在轉換時檢查集合中物件的實際執行階段型別,僅檢查 IEnumerator.Current 回傳的 System.Object 是否可轉換為迴圈宣告的型別(本例為 MyType)。

精確型別比較:GetType()

有時你需要知道物件的精確型別,而不僅是滿足可轉換的目標型別。as 運算子對任何衍生自目標型別的物件都會回傳非 null。GetType() 取得物件的執行階段型別,提供比 is 和 as 更嚴格的型別測試。其回傳的型別可與指定型別比較,以確認是否為所需型別。

繼承情境下的行為差異

若新增衍生自 MyType 的 NewType,儲存 NewType 物件的集合可在 UseCollection 中正常運作。若函數需對所有 MyType 執行個體運作,此做法不錯;但若僅針對精確的 MyType 物件,必須在迴圈內部進行精確型別比較。多數情況下,執行階段確定精確型別在物件相等性測試時最重要;其他比較中,is 和 as 提供的 isinst(IL 指令)比較在語意上已正確。

總結

良好的物件導向實務建議避免型別轉換,但無法避免時,請用 C# 提供的 is 和 as 運算子清楚表達意圖。不同轉換方法有不同規則,is/as 在絕大多數轉換上語意正確,且當目標型別正確時總會成功。應選擇這些基本指令,而非可能產生意外副作用的強制轉型。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved