当代码开始"思考"
你是否厌倦了层层嵌套的if-else地狱?是否想过让代码像侦探推理一样优雅地解构数据?C#的模式匹配正是这样一把瑞士军刀,从C# 7.0到C# 12,它已悄然进化成改变编程范式的利器。
一、模式匹配的三重境界
1.1 青铜时代:Type Check(C# 7.0)
cs
if (obj is string str)
{
Console.WriteLine($"字符串长度:{str.Length}");
}
-
is
表达式同时完成类型检查和赋值 -
告别冗长的
as
转换和null检查
1.2 白银时代:Switch表达式(C# 8.0)
cs
var result = shape switch
{
Circle c => $"半径{c.Radius}的圆",
Rectangle { Width: var w, Height: h } when w == h => $"边长{w}的正方形",
_ => "未知形状"
};
-
声明式匹配取代命令式分支
-
属性模式+条件判断一气呵成
1.3 黄金时代:递归模式(C# 10+)
cs
if (person is Professor { Students: [_, .., { Name: "Alice" }] })
{
Console.WriteLine("找到带Alice的教授!");
}
-
深度嵌套数据结构的精准打击
-
列表模式匹配+属性解构
二、四大实战黑科技
2.1 元组解构:多条件联合判断
cs
var outcome = (statusCode, errorMessage) switch
{
(200, _) => "成功",
(404, "Not Found") => "资源丢失",
(500, string msg) when msg.Contains("timeout") => "超时错误",
_ => "未知错误"
};
2.2 性能优化:避免装箱的秘诀
cs
public static bool IsLetter(this char c) =>
c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z');
// 直接操作Unicode值,无需转换为字符串
2.3 动态类型终结者
cs
string Describe(object obj) => obj switch
{
int i => $"整数{i}",
DateTime dt => dt.ToString("yyyy-MM-dd"),
IEnumerable<int> numbers => $"数字序列,总和:{numbers.Sum()}",
_ => "其他类型"
};
2.4 自定义模式匹配器
cs
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 不要忽视顺序陷阱
cs
case int i when i > 10: // 这个分支永远不会触发
case int i:
case > 10: // C# 11关系模式要放在前面
3.2 不要滥用var模式
cs
if (obj is var temp) // 总是匹配成功!可能引入隐蔽bug
3.3 不要忘记穷尽性检查
cs
// 开启编译器警告
#nullable enable
switch (nullableValue)
{
case string s: ...
// 缺少null处理分支会触发CS8509警告
}
3.4 不要忽视性能代价
高频调用时优先考虑多态而非模式匹配
3.5 不要混淆声明空间
cs
if (e is { X: > 0, Y: var y1 })
{
int y2 = y1; // 正确
}
// y1在此处不可见,作用域仅限于模式
四、与类型系统的灵魂共鸣
4.1 记录类型(Record)的完美搭档
cs
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 解构函数+位置模式
cs
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 列表模式增强
cs
if (list is [var first, .. var middle, var last])
{
// 轻松获取首尾元素
}
5.2 Span模式匹配优化
cs
ReadOnlySpan<char> span = "12345";
if (span is ['1', .., '5'])
{
// 高性能内存操作
}
当模式匹配遇上现代C#,代码不再是冰冷的指令集,而成为描述业务逻辑的诗篇。它带来的不仅是语法的简化,更是思维方式的升级------从"怎么做"到"是什么"的范式转变。