類型安全是 .NET 設計的核心。在繼承體系與多型場景下,如何安全、高效地進行類型轉換?is 與 as 運算子提供了比傳統強制轉型 (T)obj 更優雅、更安全的方案。本文將深入剖析兩者的運作規則、效能差異與最佳實踐模式。
1. .NET 類型轉換基礎規則
- 向基類轉換:隱式安全(
Derived → Base)
- 向衍生類轉換:需顯式強制轉型(
(Derived)baseObj),失敗拋 InvalidCastException
- 取得精確型別:
obj.GetType()
- 基本型別轉換:
Convert 類、Parse 方法
- 值/引用類型互轉:裝箱/拆箱
2. is 運算子:類型相容性檢查器
| 特性 | 說明 |
| 回傳值 | bool(相容 true / 不相容 false) |
| 例外處理 | 絕不拋出例外 |
| null 處理 | 運算元為 null 時永遠回傳 false |
| 典型模式 | 雙重檢查模式(反模式,效能差) |
// 典型但低效的 is 用法:兩次類型檢查
if (obj is MyType) {
MyType mt = (MyType)obj; // 第二次檢查
// ...
}
3. as 運算子:安全轉型器
| 特性 | 說明 |
| 回傳值 | 相容→物件參考;不相容→null |
| 例外處理 | 絕不拋出例外(轉型本身) |
| null 風險 | 後續若未檢查 null 直接呼叫成員,拋 NullReferenceException |
| 適用限制 | 僅限參考類型與可為 null 的值類型 |
| 效能優勢 | 單次類型檢查,優於 is + 強制轉型 |
// 標準 as 模式:單次檢查 + null 判斷
MyType mt = obj as MyType;
if (mt != null) {
mt.DoSomething(); // 安全使用
}
4. 核心差異與選擇指南
| 場景 | 推薦 | 理由 |
| 僅需判斷型別,不需轉換 | is | 語意清晰,回傳 bool 直觀 |
| 需轉換並使用結果 | as + null 檢查 | 單次檢查,效能更佳,程式碼簡潔 |
| 確定轉換必定成功 | (T)obj | 最直接,失敗即為 Bug 應拋出例外 |
| 值類型轉換 | Nullable<T> + as 或模式比對 | as 不支援非 nullable 值類型 |
5. 現代 C# 模式比對 (C# 7+)
// is 型別模式:宣告與檢查合一
if (obj is MyType mt) {
mt.DoSomething(); // mt 直接可用,無需額外轉型
}
// switch 表達式模式比對
var result = obj switch {
MyType mt => mt.Process(),
OtherType ot => ot.Handle(),
_ => DefaultAction()
};
6. 結語
as 以單次檢查贏得效能優勢,is 在純判斷場景語意更清晰。現代 C# 的模式比對進一步融合了兩者優點。實戰中請根據語境選擇:需要結果用 as,只要判斷用 is,確定成功用強制轉型。