在 C# 中,is 和 as 都用於類型檢查和類型轉換,但它們的行為、用途和安全性有顯著區別。下面詳細對比:
✅ 一句話總結區別
|
關鍵字
|
作用
|
安全性
|
返回值
|
|
|
檢查對象是否是指定類型(只判斷,不轉換) |
安全
|
|
|
|
嘗試將對象轉換為指定類型(安全轉換) |
安全
|
轉換後的引用,或 |
❗ 兩者都不會拋出
InvalidCastException(與直接強制轉換(T)obj不同)。
🔍 詳細對比 + 示例
1️⃣ is:僅做類型檢查
object obj = "Hello";
// 檢查 obj 是否是 string 類型
if (obj is string)
{
Console.WriteLine("obj 是字符串");
// 注意:這裏 obj 還是 object 類型!
// 如果要使用 string 方法,仍需轉換
string s = (string)obj; // 或用 as / 模式匹配
}
✅ C# 7.0+ 增強:is 模式匹配(推薦!)
if (obj is string s) // 同時檢查 + 轉換
{
Console.WriteLine($"內容: {s.ToUpper()}"); // s 已是 string 類型!
}
💡 這是現代 C# 中最常用的寫法,避免重複轉換。
2️⃣ as:嘗試安全轉換
object obj = "Hello";
// 嘗試轉換為 string
string s = obj as string;
if (s != null)
{
Console.WriteLine(s.ToUpper());
}
else
{
Console.WriteLine("轉換失敗");
}
⚠️ 重要限制:
as只能用於引用類型或可空值類型(不能用於int,DateTime等非可空值類型)
object num = 123;
int? n = num as int?; // ✅ 可以(因為 int? 是可空值類型)
int m = num as int; // ❌ 編譯錯誤!as 不能用於非可空值類型
🆚 對比表格
|
特性
|
|
|
|
主要目的 |
類型判斷
|
安全類型轉換
|
|
返回類型 |
|
目標類型(或 |
|
是否執行轉換 |
否(除非用模式匹配)
|
是
|
|
支持值類型 |
✅(如 |
❌(除非是 |
|
性能 |
略快(只檢查)
|
略慢(檢查 + 轉換)
|
|
典型場景 |
條件判斷
|
避免異常的安全轉換
|
❌ 錯誤用法 vs ✅ 正確用法
場景:處理未知對象
❌ 危險:直接強制轉換(可能拋異常)
try
{
string s = (string)obj; // 如果 obj 不是 string,拋 InvalidCastException
}
catch (InvalidCastException) { ... }
✅ 推薦:用 is + 模式匹配(C# 7+)
if (obj is string s)
{
// 安全使用 s
}
✅ 或用 as(適合後續多次使用)
var s = obj as string;
if (s != null)
{
// 使用 s
}
📌 最佳實踐建議
- 優先使用
is模式匹配(C# 7+):
if (animal is Dog dog)
{
dog.Bark();
}
- 代碼簡潔
- 類型安全
- 無額外轉換開銷
- 當需要多次使用轉換結果時,考慮
as:
var dog = animal as Dog;
if (dog != null)
{
dog.Bark();
dog.Fetch();
}
- 不要對值類型用
as(除非是Nullable<T>):
// 錯誤
int i = obj as int; // 編譯失敗
// 正確
if (obj is int i) { ... }
- 避免
is+ 強制轉換的組合(冗餘):
// 不推薦
if (obj is string)
{
string s = (string)obj; // 多此一舉
}
// 推薦
if (obj is string s) { ... }
✅ 總結
|
你想要...
|
用哪個?
|
|
只是判斷類型 |
|
|
判斷並立即使用轉換後的值 |
|
|
安全轉換,且後續多次使用 |
|
|
確定類型並強制轉換(不怕異常) |
|
🧠 記住:
“is問‘是不是’,as説‘試試看,不行就 null’。”
在現代 C# 開發中,is 模式匹配是最優雅、高效的選擇,應作為首選。
問題
常規轉換和使用as關鍵字轉換有什麼區別
如果使用as進行轉換失敗,結果將簡單地為null。
當常規轉換失敗時,將拋出InvalidCastException無效轉換異常
為什麼只能使用as關鍵字將對象轉換為可空類型
因為如果as轉換失敗,則返回null,null只能賦值給可空類型