2026-05-17
C#
0

目录

🔧 开篇钩子
📌 上节回顾
💡 核心知识讲解
什么是模式匹配?先用工厂类比理解
switch 表达式 vs 传统 switch 语句
模式一:常量模式(你其实已经用过了)
模式二:关系模式——直接写大于小于
14 继续增强的特性。
模式三:逻辑模式——and / or / not 三剑客
模式四:属性模式——直接匹配对象的字段
模式五:类型模式——先判断类型再处理
💻 VS2026 操作步骤
📋 完整代码示例
🏭 工业实战小案例
⚠️ 避坑提醒
📝 本节总结

🔧 开篇钩子

注塑车间,凌晨两点。

你盯着屏幕上的报警记录,模具温度传感器上传了一串数值:218.5

这个值到底是"正常"、"预警"还是"紧急停机"?

你打开代码,看到的是这样一坨东西:

if (temp > 200) { if (temp > 230) { if (isRunning) { ... } else { ... } } }

三层嵌套,改一个阈值,要找半天。

用C# 14的switch模式匹配,这坨代码可以变成5行。 今天这节,就教你怎么写。


📌 上节回顾

「上一节我们学了条件语句,掌握了用 if / else if / switch 控制程序走向的方法。

今天在这个基础上,我们进一步学习 C# 14 中 switch 表达式的模式匹配进阶写法——

让条件判断从"能用"升级到"好用、易维护"。」


💡 核心知识讲解

什么是模式匹配?先用工厂类比理解

你在车间做质检,手里拿着一个零件,要判断它"合格"、"返工"还是"报废"。

你的判断依据可能是:重量范围、表面状态、尺寸是否在公差内……

这就是**模式匹配(Pattern Matching)**的本质——

根据一个值的多种特征,快速决定它"属于哪一类",然后执行对应的处理。

C# 14 把这件事做得极其优雅。


switch 表达式 vs 传统 switch 语句

先看一下两种写法的对比:

对比维度传统 switch 语句C# 14 switch 表达式
写法需要 case: + break;用 = > 直接返回值
返回值需要额外赋值表达式本身就是值
代码量少30%~50%
可读性嵌套多了就乱结构清晰,一眼看懂

「switch 表达式是"有返回值的switch",整个结构本身就是一个值。」


模式一:常量模式(你其实已经用过了)

最基础的一种,匹配具体的值:

csharp
// 根据设备运行模式代码返回中文描述 string modeDesc = deviceModeCode switch { 0 => "停机", 1 => "手动", 2 => "自动", 3 => "调试", _ => "未知模式" // _ 是"兜底",相当于 default };

_弃元模式(Discard Pattern),相当于 default,必须放在最后。


模式二:关系模式——直接写大于小于

这是 C# 9 引入、C# 14 继续增强的特性。

不用再写 if (temp > 200 && temp <= 230),直接在 switch 里写:

csharp
// 根据模具温度值判断报警等级 string alarmLevel = moldTemp switch { < 50.0 => "低温预警", >= 50.0 and < 180.0 => "正常范围", >= 180.0 and < 230.0 => "高温预警", >= 230.0 => "紧急停机", };

注意这里的 and——这就是下一个模式的核心。


模式三:逻辑模式——and / or / not 三剑客

模式匹配支持直接用 andornot 组合条件,像写自然语言一样:

csharp
// 判断压力值是否在安全区间 bool isSafeZone = hydraulicPressure is >= 10.0 and <= 25.0; // 判断设备是否处于非正常工作状态 bool isAbnormal = deviceStatus is not (1 or 2);

「注意:not 的优先级比 and 高,复杂条件记得加括号,否则结果会出乎意料。」


模式四:属性模式——直接匹配对象的字段

如果你的数据是一个对象(比如设备信息类),属性模式可以直接"拆开对象看里面":

csharp
// 设备信息数据类 public record DeviceInfo(string Name, double Temperature, bool IsRunning); // 根据设备对象的属性组合判断状态 string GetDeviceStatus(DeviceInfo device) => device switch { { IsRunning: false } => "已停机", { IsRunning: true, Temperature: < 50.0 } => "低温运行", { IsRunning: true, Temperature: >= 230.0 } => "高温停机!", { IsRunning: true } => "正常运行", _ => "状态未知" };

{ 属性名: 模式 } 的格式,可以同时检查多个属性,不需要手动拆开对象


模式五:类型模式——先判断类型再处理

工业系统里,经常有"多种传感器上传同一个接口"的场景。

类型模式让你优雅地处理这种多态情况:

csharp
// 根据传感器类型分别处理 string ProcessSensor(object sensorData) => sensorData switch { TemperatureSensor t => $"温度传感器:{t.Value}°C", PressureSensor p => $"压力传感器:{p.Value} MPa", VibrationSensor v => $"振动传感器:{v.Amplitude} mm/s", null => "传感器数据为空", _ => "未知传感器类型" };

匹配成功后,变量 tpv 已经是对应类型,不需要再强制转换


💻 VS2026 操作步骤

Step 1 新建控制台项目

打开 VS2026,选择 文件 > 新建 > 项目,搜索"控制台应用",目标框架选 .NET 10,语言版本默认即为 C# 14

💡 VS2026 Copilot 辅助:在项目名称输入框旁,Copilot 会根据你最近的项目历史,自动推荐命名风格和目录位置,直接回车接受即可。

Step 2 确认 C# 14 语言版本

打开 .csproj 文件,确认包含以下节点(.NET 10 项目默认已包含):

xml
<LangVersion>14</LangVersion>

如果没有,手动添加在 <PropertyGroup> 内。

Step 3 编写 switch 表达式代码

Program.cs 中直接编写。VS2026 内置智能提示会在你输入 switch 时,自动弹出"转换为 switch 表达式"的建议——

点击灯泡图标,可以一键把旧的 if-else 或 switch 语句转换为 switch 表达式

Step 4 运行与调试

F5 运行。如果 switch 表达式未覆盖所有可能的值,编译器会报 CS8509 警告,提示你补充 _ 兜底分支。

🤖 Vibe Coding Prompt 写法

如果你想用 Copilot 生成模式匹配代码,可以这样描述:

"帮我写一个 C# 14 的 switch 表达式,输入是一个 double 类型的温度值 moldTemp,分别对应:低于50输出'低温预警',50到180输出'正常',180到230输出'高温预警',230以上输出'紧急停机',使用关系模式和 and 逻辑组合。"

Copilot 会直接生成完整的 switch 表达式,你只需要核对阈值是否符合你的工艺要求。


📋 完整代码示例

这段代码实现了一个注塑机多参数状态综合判断系统,综合运用了关系模式、逻辑模式和属性模式。

csharp
// ============================================================ // 注塑机多参数状态判断示例 // 环境:VS2026 / .NET 10 / C# 14 // ============================================================ using System; // 注塑机实时数据记录(使用 record 简化定义) public record InjectionMachineData( string MachineName, double MoldTemp, // 模具温度(°C) double HydraulicPressure, // 液压压力(MPa) int ProductionCount, // 本班产量 bool IsRunning // 是否运行中 ); public class MachineStatusAnalyzer { // 根据模具温度判断温度报警等级(关系模式 + and 逻辑) public static string GetTempAlarmLevel(double moldTemp) => moldTemp switch { < 30.0 => "🔵 低温停机", >= 30.0 and < 160.0 => "🟢 正常预热", >= 160.0 and < 220.0 => "🟡 工艺温度", >= 220.0 and < 260.0 => "🟠 高温预警", >= 260.0 => "🔴 紧急停机!", }; // 根据液压压力判断是否在安全区间(逻辑模式) public static string CheckHydraulicSafety(double hydraulicPressure) { // is 表达式配合关系模式,直接返回布尔值 bool isSafe = hydraulicPressure is >= 8.0 and <= 22.0; bool isOverPressure = hydraulicPressure is > 22.0; return (isSafe, isOverPressure) switch { (true, _) => "液压正常", (false, true) => "液压过高,请检查溢流阀", (false, false) => "液压不足,请检查油泵", }; } // 根据整机数据对象综合判断设备状态(属性模式) public static string GetMachineOverallStatus(InjectionMachineData data) => data switch { // 先判断停机状态 { IsRunning: false, ProductionCount: 0 } => "待机中", // 停机但有产量——换班或计划停机 { IsRunning: false, ProductionCount: > 0 } => $"本班已完成 {data.ProductionCount} 件,已停机", // 运行中但温度异常 { IsRunning: true, MoldTemp: >= 260.0 } => $"⚠️ 高温紧急停机!当前温度:{data.MoldTemp}°C", // 运行中且压力异常 { IsRunning: true, HydraulicPressure: > 22.0 } => $"⚠️ 液压超限!当前压力:{data.HydraulicPressure} MPa", // 正常运行 { IsRunning: true } => $"✅ 正常运行,本班产量:{data.ProductionCount} 件", _ => "状态未知,请检查传感器连接" }; } // 主程序入口 class Program { static void Main() { Console.OutputEncoding=System.Text.Encoding.UTF8; // 支持输出表情符号 // 模拟几组设备数据 var machines = new[] { new InjectionMachineData("1号注塑机", 185.0, 15.5, 342, true), new InjectionMachineData("2号注塑机", 267.0, 16.0, 128, true), new InjectionMachineData("3号注塑机", 45.0, 0.0, 0, false), new InjectionMachineData("4号注塑机", 175.0, 24.5, 89, true), }; foreach (var machine in machines) { Console.WriteLine($"【{machine.MachineName}】"); Console.WriteLine($" 温度状态:{MachineStatusAnalyzer.GetTempAlarmLevel(machine.MoldTemp)}"); Console.WriteLine($" 液压状态:{MachineStatusAnalyzer.CheckHydraulicSafety(machine.HydraulicPressure)}"); Console.WriteLine($" 综合状态:{MachineStatusAnalyzer.GetMachineOverallStatus(machine)}"); Console.WriteLine(); } } }

image.png

运行后,控制台会按设备逐条输出温度状态、液压状态和综合运行状态。

你会看到2号机因温度超过260°C触发了高温紧急停机提示,4号机因液压超过22 MPa触发了液压超限警告。

整个判断逻辑,没有一个嵌套的 if-else,代码从上到下读下来,就像在看一张工艺参数检查表。


🏭 工业实战小案例

场景任务: 光伏电站逆变器巡检系统,需要根据逆变器上传的直流输入电压值,自动判断当前工况并生成巡检结论。

思路拆解:

  • 定义电压值的五个区间:离网/低压/正常/高压/过压
  • 用关系模式 + and 组合直接覆盖所有区间
  • 用 switch 表达式返回工况描述字符串
  • 同时输出是否需要派人处理的布尔结论
  • 整个逻辑无需任何 if-else,一个 switch 搞定
csharp
// 光伏逆变器直流输入电压工况判断 // 适用于组串式逆变器,额定输入电压范围 200V~800V public class InverterInspector { // 电压区间说明(单位:V) // < 150 离网/夜间 // 150~199 低压预警(可能有遮挡) // 200~800 正常工况 // 801~900 高压预警 // > 900 过压保护,需停机检查 public record InspectionResult(string Condition, bool NeedsAttention); public static InspectionResult CheckDcVoltage(double dcInputVoltage) => dcInputVoltage switch { < 150.0 => new("离网/夜间,无输出", false), >= 150.0 and < 200.0 => new("直流低压,检查是否有组件遮挡或断路", true), >= 200.0 and <= 800.0 => new("正常工况,发电正常", false), > 800.0 and <= 900.0 => new("直流高压预警,检查汇流箱是否串联过多组串", true), > 900.0 => new("过压保护触发!已停机,立即排查组件绝缘", true), }; } // 调用示例 class Program { static void Main() { Console.OutputEncoding= System.Text.Encoding.UTF8; // 支持输出中文和表情符号 double[] testVoltages = { 0.0, 165.0, 550.0, 850.0, 920.0 }; foreach (var voltage in testVoltages) { var result = InverterInspector.CheckDcVoltage(voltage); string flag = result.NeedsAttention ? "⚠️ 需处理" : "✅ 正常"; Console.WriteLine($"电压 {voltage,6}V → {flag} | {result.Condition}"); } } }

image.png

运行后,控制台按电压值逐行输出工况判断结果和是否需要派人处理的标记。

五种电压场景,代码只有一个 switch 表达式,没有任何嵌套,巡检系统的核心逻辑一眼就能看清楚。


⚠️ 避坑提醒

「这几个坑,我替你踩过了」

坑一:忘了写 _ 兜底,编译器只给警告不报错

❌ 错误做法:switch 表达式只写了几个具体分支,没有 _

✅ 正确做法:最后一行加上 _ => throw new ArgumentOutOfRangeException(...)_ => "未知状态"

📌 原因:C# 编译器只会给 CS8509 警告,程序照样能跑,但运行时一旦遇到没覆盖的值,直接抛 SwitchExpressionException,车间现场崩了你才知道。


坑二:notand 的优先级踩坑

❌ 错误做法:value is not >= 10 and <= 100(本意是"不在10到100之间")

✅ 正确做法:value is not (>= 10 and <= 100)

📌 原因:not 优先级比 and 高,不加括号会被解析成 (not >= 10) and <= 100,逻辑完全不对,而且编译器不会报错,这是纯逻辑 bug。


坑三:属性模式的匹配顺序很重要

❌ 错误做法:把范围宽的分支写在前面,导致后面的精确分支永远匹配不到

✅ 正确做法:精确条件在前,宽泛条件在后_ 永远放最后

📌 原因:switch 表达式从上到下逐个匹配,第一个命中就返回,后面的分支不再检查。顺序写错,等于白写。


📝 本节总结

「学完本节,你掌握了:」

C# 14 的 switch 表达式让判断逻辑从"语句"变成了"值",写法更紧凑,意图更清晰。你学会了用关系模式直接写大于小于区间,用 and / or / not 组合复杂条件,用属性模式直接对对象的字段做判断,还学会了类型模式处理多态传感器数据。这几种模式可以自由嵌套组合,工业场景里的绝大多数条件判断,都能用它们优雅地表达。

从今天起,遇到嵌套 if-else,先想想能不能换成 switch 表达式——代码量少了,逻辑清晰了,同事接手也不骂你了。


📖 本文是《C# 工业数字化应用开发专家》系列第 015 节

上一节:【条件语句:if、else if、switch】

下一节:【循环语句:for、while、do-while、foreach】(明天更新)

💬 你在工作中遇到过类似的需求吗?

设备报警分级、工况判断、传感器类型分发……这些场景你们厂是怎么写的?欢迎在评论区说说你的情况,也许下一篇案例就来自你的留言。

🔔 还没关注的同学记得点击关注,系列课程持续更新,学完这420节,从工厂小白到工业软件开发专家,我们一起走。


#工业数字化 #C#编程 #工厂自动化 #制造业IT #程序员成长

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!