注塑车间,凌晨两点。
你盯着屏幕上的报警记录,模具温度传感器上传了一串数值: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 语句 | 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 组合条件,像写自然语言一样:
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 => "传感器数据为空",
_ => "未知传感器类型"
};
匹配成功后,变量 t、p、v 已经是对应类型,不需要再强制转换。
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();
}
}
}

运行后,控制台会按设备逐条输出温度状态、液压状态和综合运行状态。
你会看到2号机因温度超过260°C触发了高温紧急停机提示,4号机因液压超过22 MPa触发了液压超限警告。
整个判断逻辑,没有一个嵌套的 if-else,代码从上到下读下来,就像在看一张工艺参数检查表。
场景任务: 光伏电站逆变器巡检系统,需要根据逆变器上传的直流输入电压值,自动判断当前工况并生成巡检结论。
思路拆解:
and 组合直接覆盖所有区间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}");
}
}
}

运行后,控制台按电压值逐行输出工况判断结果和是否需要派人处理的标记。
五种电压场景,代码只有一个 switch 表达式,没有任何嵌套,巡检系统的核心逻辑一眼就能看清楚。
「这几个坑,我替你踩过了」
坑一:忘了写 _ 兜底,编译器只给警告不报错
❌ 错误做法:switch 表达式只写了几个具体分支,没有 _
✅ 正确做法:最后一行加上 _ => throw new ArgumentOutOfRangeException(...) 或 _ => "未知状态"
📌 原因:C# 编译器只会给 CS8509 警告,程序照样能跑,但运行时一旦遇到没覆盖的值,直接抛 SwitchExpressionException,车间现场崩了你才知道。
坑二:not 和 and 的优先级踩坑
❌ 错误做法: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 许可协议。转载请注明出处!