當代碼開始"思考"
你是否厭倦了層層嵌套的if-else地獄?是否想過讓代碼像偵探推理一樣優雅地解構數據?C#的模式匹配正是這樣一把瑞士軍刀,從C# 7.0到C# 12,它已悄然進化成改變編程范式的利器。
一、模式匹配的三重境界
1.1 青銅時代:Type Check(C# 7.0)
if (obj is string str)
{Console.WriteLine($"字符串長度:{str.Length}");
}
-
is
表達式同時完成類型檢查和賦值 -
告別冗長的
as
轉換和null檢查
1.2 白銀時代:Switch表達式(C# 8.0)
var result = shape switch
{Circle c => $"半徑{c.Radius}的圓",Rectangle { Width: var w, Height: h } when w == h => $"邊長{w}的正方形",_ => "未知形狀"
};
-
聲明式匹配取代命令式分支
-
屬性模式+條件判斷一氣呵成
1.3 黃金時代:遞歸模式(C# 10+)
if (person is Professor { Students: [_, .., { Name: "Alice" }] })
{Console.WriteLine("找到帶Alice的教授!");
}
-
深度嵌套數據結構的精準打擊
-
列表模式匹配+屬性解構
二、四大實戰黑科技
2.1 元組解構:多條件聯合判斷
var outcome = (statusCode, errorMessage) switch
{(200, _) => "成功",(404, "Not Found") => "資源丟失",(500, string msg) when msg.Contains("timeout") => "超時錯誤",_ => "未知錯誤"
};
2.2 性能優化:避免裝箱的秘訣
public static bool IsLetter(this char c) =>c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z');
// 直接操作Unicode值,無需轉換為字符串
2.3 動態類型終結者
string Describe(object obj) => obj switch
{int i => $"整數{i}",DateTime dt => dt.ToString("yyyy-MM-dd"),IEnumerable<int> numbers => $"數字序列,總和:{numbers.Sum()}",_ => "其他類型"
};
2.4 自定義模式匹配器
public static class Extensions
{public static bool IsPrime(this int n) => n > 1 && Enumerable.Range(2, (int)Math.Sqrt(n)-1).All(i => n % i != 0);
}// 使用
var result = number switch
{int x when x.IsPrime() => "質數",_ => "非質數"
};
三、模式匹配的五個"不要"
3.1 不要忽視順序陷阱
case int i when i > 10: // 這個分支永遠不會觸發
case int i:
case > 10: // C# 11關系模式要放在前面
3.2 不要濫用var模式
if (obj is var temp) // 總是匹配成功!可能引入隱蔽bug
3.3 不要忘記窮盡性檢查
// 開啟編譯器警告
#nullable enable
switch (nullableValue)
{case string s: ... // 缺少null處理分支會觸發CS8509警告
}
3.4 不要忽視性能代價
高頻調用時優先考慮多態而非模式匹配
3.5 不要混淆聲明空間
if (e is { X: > 0, Y: var y1 })
{ int y2 = y1; // 正確
}
// y1在此處不可見,作用域僅限于模式
四、與類型系統的靈魂共鳴
4.1 記錄類型(Record)的完美搭檔
public record Order(int Id, List<Item> Items);var discount = order switch
{{ Items.Count: > 10 } => 0.2m,{ Items: [{ Price: > 100 }, ..] } => 0.1m,_ => 0
};
4.2 解構函數+位置模式
public readonly struct Point(int x, int y)
{public void Deconstruct(out int X, out int Y) => (X, Y) = (x, y);
}var quadrant = point switch
{( > 0, > 0 ) => 1,( < 0, > 0 ) => 2,( < 0, < 0 ) => 3,( > 0, < 0 ) => 4,_ => 0
};
五、未來展望:C# 12模式匹配新紀元
5.1 列表模式增強
if (list is [var first, .. var middle, var last])
{// 輕松獲取首尾元素
}
5.2 Span模式匹配優化
ReadOnlySpan<char> span = "12345";
if (span is ['1', .., '5'])
{// 高性能內存操作
}
當模式匹配遇上現代C#,代碼不再是冰冷的指令集,而成為描述業務邏輯的詩篇。它帶來的不僅是語法的簡化,更是思維方式的升級——從"怎么做"到"是什么"的范式轉變。