从“Switch-case“到“智能模式“:C#模式匹配的终极进化指南

当代码开始"思考"

你是否厌倦了层层嵌套的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#,代码不再是冰冷的指令集,而成为描述业务逻辑的诗篇。它带来的不仅是语法的简化,更是思维方式的升级------从"怎么做"到"是什么"的范式转变。

相关推荐
阿隆_趣编程3 分钟前
为了方便相亲,我用AI写了一款小程序
前端·javascript·微信小程序
EndingCoder15 分钟前
Electron 跨平台兼容性:处理 OS 差异
前端·javascript·electron·前端框架·node.js·chrome devtools
秦禹辰21 分钟前
宝塔面板安装MySQL数据库并通过内网穿透工具实现公网远程访问
开发语言·后端·golang
黄焖鸡能干四碗27 分钟前
智慧教育,智慧校园,智慧安防学校建设解决方案(PPT+WORD)
java·大数据·开发语言·数据库·人工智能
秋田君31 分钟前
Vue3+Node.js 实现大文件上传:断点续传、秒传、分片上传完整教程(含源码)
前端
爱隐身的官人31 分钟前
ctfshow - web - nodejs
前端·nodejs·ctf
zhong liu bin31 分钟前
Vue框架技术详解——项目驱动概念理解【前端】【Vue】
前端·javascript·vue.js·vscode·vue
W-GEO31 分钟前
前端安全攻防:XSS, CSRF 等常见威胁的防范与检测指南
前端·安全·xss
2301_8035545234 分钟前
实习项目包装--HTTP 协议和 Web API
前端·网络协议·http
lssjzmn35 分钟前
Spring Web 异步响应实战:从 CompletableFuture 到 ResponseBodyEmitter 的全链路优化
java·前端·后端·springboot·异步·接口优化