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

C# is 運算子完整指南:型別相容性檢查、模式比對與現代語法演進

     編輯:關於C#

is 運算子是 C# 型別系統的核心檢查工具,從簡單的型別相容性測試演進為強大的模式比對引擎 (C# 7.0+)。它不執行轉型,只回傳 bool,零副作用,是防禦性程式設計的首選。

核心語意:型別相容性檢查

運算式 is 目標類型
// 檢查:運算式結果是否可透過參考/裝箱/拆箱轉型為目標類型
// 回傳:true / false (從不拋出例外)
// 運算式可為 null (null is T → false)

基本型別檢查範例

Console.WriteLine(1 is int);       // True  (int 相容 int)
Console.WriteLine(1 is float);     // False (int 不隱含轉型為 float)
Console.WriteLine(1.0 is float);   // False (double 不隱含轉型為 float)
Console.WriteLine(1.0 is double);  // True  (double 相容 double)
Console.WriteLine("text" is object); // True (字串繼承 object)
Console.WriteLine(null is string);   // False (null 不相容任何實值型別)

模式比對演進史

C# 1.0-6.0:單純型別檢查

if (obj is string)
{
    string s = (string)obj; // 需額外強制轉型
    Console.WriteLine(s.Length);
}

C# 7.0:型別模式 + 變數宣告

// 宣告模式:檢查成功直接宣告強型別變數
if (obj is string s) 
{
    Console.WriteLine(s.Length); // s 範圍限定在 if 區塊
}

// 範圍:s 僅在 is 為 true 的分支有效
// 外部無法存取 s (編譯器保證)

C# 9.0:關係/邏輯/否定/常數模式

// 關係模式
if (number is >= 0 and <= 100) { ... }

// 邏輯模式組合
if (input is string { Length: > 0 } or int > 0) { ... }

// 否定模式
if (obj is not null) { ... } // 等價於 !(obj is null)

// 常數模式
if (status is 200 or 201) { ... } // 比對具體值

// var 模式 (永遠匹配,引入變數)
if (obj is var x) { ... } // 等價於 var x = obj;

C# 11.0:List/切片模式 (搭配 Span/陣列)

int[] numbers = { 1, 2, 3, 4, 5 };

// 陣列長度與元素模式
if (numbers is [1, 2, .., 5]) { ... } // 開頭 1,2 結尾 5,中間任意
if (numbers is [_, _, 3, ..]) { ... } // 第三個元素為 3

// 切片模式
if (numbers is [.., > 0]) { ... } // 最後一個元素 > 0

進階模式:屬性/型別/解構模式

record Person(string Name, int Age);

var person = new Person("Alice", 30);

// 屬性模式
if (person is { Age: >= 18, Name: "Alice" }) { ... }

// 型別模式結合屬性
if (person is Person { Age: > 65 } senior) { ... }

// 解構模式 (需 Deconstruct 方法)
if (person is (string name, int age)) { ... } // 自動解構

is 運算子在 switch 運算式中的威力

// 傳統 switch (C# 7.0)
switch (shape)
{
    case Circle c: return c.Radius * c.Radius * Math.PI;
    case Rectangle r: return r.Width * r.Height;
    case null: return 0;
    default: throw new ArgumentException();
}

// 現代 switch 運算式 (C# 8.0+) — 更簡潔、運算式導向
double Area(Shape shape) => shape switch
{
    Circle { Radius: var r } => r * r * Math.PI,
    Rectangle { Width: var w, Height: var h } => w * h,
    Triangle { Base: var b, Height: var h } => 0.5 * b * h,
    null => 0,
    _ => throw new ArgumentException($"未知形狀: {shape}")
};

is vs as vs 強制轉型:決策指南

需求推薦方案理由
僅檢查型別is T零成本、無副作用、語意清晰
檢查並使用轉型後值is T var (C# 7+)單次檢查、變數範圍安全、無 null 風險
參考轉型,失敗預期為 nullas T + null 檢查舊版相容、介面轉型常用
確定轉型必成功(T)obj失敗即 Bug,拋出例外暴露問題
複雜多條件分派switch 運算式窮盡性檢查、運算式導向、效能最佳

效能特性

  • 編譯為 isinst + 分支指令 — 極快
  • 模式比對編譯為決策樹 — JIT 深度優化
  • 避免雙重檢查:if (x is T t) 優於 var t = x as T; if (t != null)
  • is not null 優於 != null (針對多載 == 的類型)

常見誤區與最佳實踐

  1. 不要寫 if ((obj is string) == true) — 多餘括號與比較
  2. 避免 is 後緊接強制轉型 — if (obj is string) { var s = (string)obj; } → 改用 if (obj is string s)
  3. 善用 is not null — 明確語意、避開運算子多載陷阱
  4. 模式比對優先於型別檢查 + 轉型 — 現代 C# 風格、編譯器保證安全
  5. switch 運算式處理聯合型別 — 窮盡性編譯檢查防遺漏

is 運算子從簡單的型別檢查進化為模式比對核心,掌握其現代語法能編寫更安全、簡潔且具表達力的型別處理邏輯。

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