1.模式匹配是什么
“模式匹配”是一种测试表达式是否具有特定特征的方法。
简单说,就是检查一个数据“长什么样”或“是什么”,然后根据这个“样子”决定程序做什么。
C# 支持多种模式,常用的大概有:
声明模式:检查表达式的运行时类型,如果匹配成功,请将表达式结果分配给声明的变量。
类型模式:检查表达式的运行时类型。
常量模式:测试表达式结果是否等于指定的常量。
关系模式:将表达式结果与指定的常量进行比较。
逻辑模式:测试表达式是否与模式的逻辑组合匹配。
弃元模式:匹配任何表达式。
(注:不用担心,我会在后面的例子中举例说明并标注)
2.Null检查
类型名称后添加 ? 符号表示该类型允许值为 null(空值),这是一个可空类型(Nullable Type)的语法。
标准类型 vs 可空类型:
- 普通
bool类型只能有两个值:true或false。 bool?类型允许三个值:true、false或null。
举个例子看看:
bool? isActive = null; // 合法,因为 bool? 允许 null
bool normalBool = null; // 编译错误!普通 bool 不能为 null
// 使用场景:检查记录是否存在
bool? hasPermission = 某一个值;//某一个值可能为true或null
if (hasPermission == true)
{
Console.WriteLine("yes");
}
else if (hasPermission == null)
{
Console.WriteLine("get null");
}
注意:直接使用可空类型前需检查是否为 null,我来举例
int? nullableInt = 某一个值; // 某一个值可能是 具体的int值 或 null
// 正确:先检查是否为 null
if (nullableInt.HasValue)
{
// 安全访问真实值
int actualValue = nullableInt.Value;
Console.WriteLine($"num is {actualValue}");
}
else
{
Console.WriteLine("num is null");
}
3.模式匹配怎么用
🎯 你只需要掌握两种用法:
3.1 is表达式(单个检查)
“is 表达式”支持通过模式匹配来测试表达式,并根据测试结果有条件地声明一个新的变量。
目的:检查表达式的类型/结构,匹配成功时同时声明一个新变量。
✅ 核心优势:检查类型的同时直接生成变量!
is 表达式的结构:
if (变量 is 类型 新变量名)
模式匹配最常见的方案之一是确保值不是 null
int? maybe = 12;
if (maybe is int number)
{
Console.WriteLine($"The int 'maybe' has the value {number}");
}
else
{
Console.WriteLine("The int 'maybe' doesn't hold a value");
}

注:
maybe is int 检查运行时 maybe 的实际类型是否为 int(类型模式的体现)
.... is int number 声明并初始化新变量 number (声明模式的体现)
双重功能:
- 先执行类型检查(类型模式)
- 成功后执行变量声明与赋值(声明模式)
模式匹配的另一种常见用途是测试变量是否与给定类型匹配。 举一个例子吧:
void CheckType(object obj)
{
// 使用is表达式进行类型检查
if (obj is int number)
{
Console.WriteLine($"this is a int: {number} (and: {number * number})");
}
else if (obj is string text)
{
Console.WriteLine($"this is a string: \"{text}\" (and: {text.Length})");
}
else if (obj is double decimalNumber)
{
Console.WriteLine($"this is a double: {decimalNumber} (and: {decimalNumber * 2})");
}
else
{
Console.WriteLine($"what: {obj.GetType().Name}");
}
}
// 测试不同的对象
CheckType(42); // 整数
CheckType("Hello World");// 字符串
CheckType(3.14); // 浮点数
CheckType(true); // 布尔值
CheckType(new object()); // 普通对象

补充: 为什么用 object 类型?
在 C# 中,object 是所有类型的基类,也就是:
int number = 42; // 值类型
string text = "Hello"; // 引用类型
// 所有类型都能赋值给object
object obj1 = number;
object obj2 = text;
3.2 switch表达式(多个检查)
“switch 表达式”允许你根据表达式的首次匹配模式执行操作。
目的:针对一个输入值,测试多种可能的模式并直接返回一个结果。
switch表达式的结构:
结果变量 = 输入值 switch
{
匹配模式1 => 结果值1,
匹配模式2 => 结果值2,
匹配模式3 => 结果值3,
_ => 默认结果值 // 必须包含的默认分支
};
工作原理:当执行switch表达式时
- 程序会从上到下依次检查每个分支
- 当找到第一个匹配的分支时,立即执行并返回对应的结果值
- 如果没有任何分支匹配,则执行默认分支(_)
- 返回的结果值被赋给左侧的结果变量
举一个使用常量模式的例子:
void HandleTrafficSignal(string? signal)
{
string action = signal switch
{
"Red" => "Stop",
"Yellow" => "wait",
"Green" => "gogogo",
null => "what",
_ => "Unknown signal"
};
Console.WriteLine($"Signal: {signal} → Action: {action}");
}
// 测试
HandleTrafficSignal("Red");
HandleTrafficSignal("Green");
HandleTrafficSignal(null);
HandleTrafficSignal("Flashing");

注:
"Red" => "Stop" 精确匹配特定字符串值(常量模式的体现)
_ => "Unknown signal" 默认处理所有未匹配的情况 (弃元模式的体现)
再举一个例子吧:
void PrintResult(int score)
{
// Switch表达式判断分数等级
string grade = score switch
{
< 50 => "Fail",
>= 50 and < 90 => "Pass",
>= 90 and <= 100 => "Distinction",
_ => "Invalid Score"
};
Console.WriteLine($"Score: {score} - {grade}");
}
//测试
PrintResult(25);
PrintResult(55);
PrintResult(95);
PrintResult(105);

注:
< 50 => "Fail" 直接使用比较运算符进行值范围匹配(关系模式的体现)
>= 50 and < 90 使用逻辑运算符 and 组合多个条件 (逻辑模式的体现)
_ => "Invalid Score" 表示"其他所有情况"(弃元模式的体现)
✅ 核心优势:
- 直接返回结果(不用先声明变量)
- 强制处理所有情况(忘写default会编译报错!)
4.枚举匹配
4.1 枚举
枚举(Enum)是一种值类型,它用于定义一组命名的整数常量。
默认情况下,枚举中的第一个元素的值是0,后面的元素依次增加1。
用星期来举例:
enum DaysOfWeek
{
Monday, // 默认值为0
Tuesday, // 1
Wednesday, // 2
Thursday, // 3
Friday, // 4
Saturday, // 5
Sunday // 6
}
当然也可以指定值:
enum StatusCode
{
OK = 200,
NotFound = 404,
ServerError = 500
}
4.2 枚举匹配使用
举个例子:现在有一个信息等级的枚举
LogLevel log = LogLevel.Warning;
enum LogLevel
{
Info,
Warning,
Error
}
先来看看如果使用传统的switch 语句
switch (log)
{
case LogLevel.Info:
Console.WriteLine("Info123");
break;
case LogLevel.Warning:
Console.WriteLine("Warning123");
break;
case LogLevel.Error:
Console.WriteLine("Error123");
break;
}
现在使用Switch 表达式:
string message = log switch
{
LogLevel.Info => "Info123",
LogLevel.Warning => "Warning123",
LogLevel.Error => "Error123",
_ => "Unknown" // 默认处理
};
现在来深入对比一下:
| 特性 | Switch 表达式 | 传统 Switch 语句 |
|---|---|---|
| 目的 | 返回值 (表达式角色) | 执行操作 (语句角色) |
| 默认处理 | 必须包含 _ 分支 | 可省略 default |
| case 语法 | 直接 成员 => 值 | case 成员: 语句块 |
| break/return | 不需要 | 必须显式使用 |
总结:
优先使用 Switch 表达式:当需要基于枚举值返回结果时,更简洁安全
传统语句适用场景:
需要执行多个独立操作的复杂逻辑;
面向早期 C# 版本的项目(< 8.0);
已有复杂 switch 语句需要维护
学到了这里,咱俩真棒,记得按时吃饭(祝你立秋快乐噢!)
【本篇结束,新的知识会不定时补充】
感谢你的阅读!如果内容有帮助,欢迎 点赞❤️ + 收藏⭐ + 关注 支持! 😊
605

被折叠的 条评论
为什么被折叠?



