| 特性 | as | is | 強制轉換 (Cast) |
|---|---|---|---|
| 語法 | obj as Type | obj is Type | (Type)obj |
| 回傳值 | 成功回傳物件,失敗回傳 null | 成功 true,失敗 false | 成功回傳物件,失敗拋 InvalidCastException |
| 適用型別 | 參考型別、可為 null 的實值型別 | 所有型別 | 所有型別 (含實值型別數值轉換) |
| 執行使用者定義轉換 | 否 | 否 | 是 (隱含/顯式運算子) |
| 效能 | 極快 (單指令) | 極快 | 快,但失敗擲例外成本高 |
| 執行緒安全 | 是 | 是 | 是 |
struct Digit
{
public int Value;
public static implicit operator int(Digit d) => d.Value;
public static explicit operator Digit(int i) => new Digit { Value = i };
}
Digit d = new Digit { Value = 42 };
int i1 = (int)d; // OK: 隱含轉換
int i2 = d as int; // 編譯錯誤: as 不能用於實值型別 (非 nullable)
int i3 = d is int ? (int)d : 0; // OK 但多餘
// 參考型別範例
object obj = "hello";
string s1 = obj as string; // "hello"
string s2 = (string)obj; // "hello"
bool b = obj is string; // true
object num = 123;
string s3 = num as string; // null (不拋例外)
string s4 = (string)num; // 拋 InvalidCastException
as,再檢查 null。
var str = obj as string;
if (str != null) { /* 使用 str */ }
is (C# 7+ 可用型別模式 obj is string s 合併判斷與轉換)。(Type)obj,失敗即為 Bug 應拋出例外。as/is 不支援 (除非 int?)。// 傳統
if (obj is string)
{
var s = (string)obj;
Console.WriteLine(s.Length);
}
// 模式比對 (合併判斷與轉換)
if (obj is string s) // s 只在 true 區塊有效
{
Console.WriteLine(s.Length);
}
// switch 表達式 (C# 8+)
string desc = obj switch
{
string s => $"String: {s.Length}",
int i => $"Int: {i}",
null => "Null",
_ => "Other"
};
// 1 億次迴圈,Release 模式,.NET 6 x64
// as + null 檢查: ~450 ms
// is + 型別模式: ~460 ms
// try-cast + catch: ~1,200 ms (例外成本極高)
// 結論: 正常路徑 as/is 差異微小,避免例外為大原則。
as 比 is 快 → 實測差異可忽略,選語意正確者。int? x = obj as int? → obj 若為 long 會回傳 null 而非轉換,需用 Convert.ToInt32 或模式比對。is + throw,內部邏輯用 as + null 檢查,確定型別時直 Cast。原文連結:https://www.bianceng.cn/Programming/csharp/201410/45592.htm