C#的switch语句通过引入模式匹配和switch表达式,实现了从简单值比较到复杂数据形状匹配的跃迁,支持类型、属性、关系等多种模式,结合执行顺序与穷尽性检查,显著提升代码可读性与安全性。

C#的
switch
if-else if
C#的
switch
switch
解决方案
我们来具体看看这些新特性是如何工作的,以及如何利用它们进行模式匹配:
1. switch
这是最直观的变化。传统的
switch
switch
=>
break
// 传统switch语句
string GetDayTypeTraditional(DayOfWeek day)
{
switch (day)
{
case DayOfWeek.Saturday:
case DayOfWeek.Sunday:
return "Weekend";
case DayOfWeek.Monday:
return "Start of Week";
default:
return "Weekday";
}
}
// switch表达式
string GetDayTypeModern(DayOfWeek day) => day switch
{
DayOfWeek.Saturday or DayOfWeek.Sunday => "Weekend", // C# 9.0 逻辑模式
DayOfWeek.Monday => "Start of Week",
_ => "Weekday" // _ 是丢弃模式,匹配任何其他情况
};2. 模式匹配的种类
switch
switch
类型模式(Type Pattern - C# 7.0) 用于检查表达式的运行时类型,并将其转换为该类型的新变量。
object data = "Hello, C#!";
string result = data switch
{
string s => $"这是一个字符串,长度是 {s.Length}",
int i => $"这是一个整数,值为 {i}",
_ => "未知类型"
};
// 也可以在传统的switch语句中使用:
// if (data is string s) { /* ... */ }var
null
object item = new List<int> { 1, 2 };
string description = item switch
{
var list when list is List<int> => $"这是一个整数列表,包含 {((List<int>)list).Count} 个元素",
_ => "其他类型"
};
// 注意:var模式通常与when子句结合使用,否则它会匹配所有非null值。属性模式(Property Pattern - C# 8.0) 允许你根据对象的属性值进行匹配。这在处理复杂对象时特别有用。
record Order(int OrderId, decimal Amount, string Status);
Order order = new(101, 150.75m, "Processing");
string orderStatusMessage = order switch
{
{ Status: "Processing", Amount: > 100m } => "大额订单正在处理中。",
{ Status: "Completed" } => "订单已完成。",
{ Status: "Cancelled", OrderId: var id } => $"订单 {id} 已取消。",
_ => "未知订单状态。"
};位置模式(Positional Pattern - C# 8.0) 用于匹配支持解构(Deconstruct)的对象。你可以根据解构后的值进行匹配。
record Point(int X, int Y); // records 默认支持解构
Point p = new(10, 20);
string pointDescription = p switch
{
(0, 0) => "原点",
(> 0, > 0) => "第一象限",
(int x, int y) when x < 0 && y > 0 => "第二象限", // 结合when子句
_ => "其他位置"
};关系模式(Relational Pattern - C# 9.0) 允许你使用关系运算符(
<
>
<=
>=
int temperature = 25;
string weatherAdvice = temperature switch
{
< 0 => "极寒,注意保暖!",
>= 0 and < 10 => "寒冷,多穿衣服。", // C# 9.0 逻辑模式结合
>= 10 and < 25 => "舒适宜人。",
>= 25 and < 35 => "炎热,注意防晒。",
_ => "酷暑,避免外出!"
};逻辑模式(Logical Pattern - C# 9.0) 使用
and
or
not
bool IsWorkingDay(DayOfWeek day) => day switch
{
DayOfWeek.Saturday or DayOfWeek.Sunday => false,
not DayOfWeek.Friday => true, // 除了周五以外的工作日
_ => true // 周五也是工作日
};这些模式可以灵活组合,形成非常强大和富有表达力的匹配逻辑。在我看来,
switch
switch
switch
在我个人的编程实践中,
switch
switch
switch
switch
switch
传统的
switch
case
break
// switch 语句:执行副作用
void ProcessCommand(string command)
{
switch (command)
{
case "start":
Console.WriteLine("Starting service...");
// 更多启动逻辑
break;
case "stop":
Console.WriteLine("Stopping service...");
// 更多停止逻辑
break;
default:
Console.WriteLine("Unknown command.");
break;
}
}而
switch
=>
// switch 表达式:计算并返回一个值
string GetServiceStatus(ServiceState state) => state switch
{
ServiceState.Running => "Service is active.",
ServiceState.Stopped => "Service is inactive.",
ServiceState.Error => "Service encountered an error.",
_ => "Unknown service state."
};如何选择?
我的经验是:
switch
switch
if-else if
当然,两者并非完全互斥。有时候,你可能在
switch
在我看来,C#的模式匹配并非仅仅是语法上的“锦上添花”,它实实在在地解决了许多在日常开发中遇到的痛点,让代码变得更具弹性、更安全,也更容易维护。
处理多态类型集合时的繁琐判断: 想象一下,你有一个
List<object>
if (obj is TypeA a) { ... } else if (obj is TypeB b) { ... }else
List<object> items = new() { 10, "hello", new DateTime(2023, 1, 1), 3.14f };
foreach (var item in items)
{
string description = item switch
{
int i => $"整数: {i}",
string s => $"字符串: '{s}' ({s.Length} chars)",
DateTime dt => $"日期: {dt.ToShortDateString()}",
float f => $"浮点数: {f:F2}",
_ => "未知类型"
};
Console.WriteLine(description);
}这让处理异构集合变得异常优雅,代码结构清晰,且编译器能帮助检查是否覆盖了所有可能的类型(对于
switch
复杂的业务规则或状态机逻辑: 当你的业务逻辑涉及到多个条件组合时,比如一个订单的状态、金额、用户等级等共同决定某个操作的权限或结果,传统的
if-else if
record User(string Name, UserRole Role, bool IsActive);
record Order(int Id, decimal Amount, OrderStatus Status);
enum UserRole { Guest, Member, Admin }
enum OrderStatus { Pending, Processing, Completed, Cancelled }
bool CanProcessOrder(User user, Order order) => (user, order) switch
{
({ Role: UserRole.Admin }, _) => true, // 管理员可以处理任何订单
({ IsActive: true, Role: UserRole.Member }, { Status: OrderStatus.Pending or OrderStatus.Processing, Amount: <= 1000m }) => true, // 活跃会员可以处理小额待处理或处理中订单
({ IsActive: false }, _) => false, // 非活跃用户不能处理
(_, { Status: OrderStatus.Completed or OrderStatus.Cancelled }) => false, // 已完成或已取消的订单不能再处理
_ => false // 其他情况均不能处理
};这种方式将复杂的条件判断逻辑集中在一个地方,并且可读性极高,一眼就能看出不同组合下的行为。
空值(null)检查的简化: 虽然C# 8.0引入了可空引用类型,但显式的
null
null
object? value = null; // 或者 new object();
string info = value switch
{
null => "值为空。",
string s => $"这是一个字符串:{s}",
_ => "非空但非字符串。"
};这避免了单独写
if (value is null)
模式匹配的这些能力,让我在编写业务逻辑时,能够更专注于“数据是什么样子”,而不是“如何一步步判断它”,从而写出更声明式、更易于理解和维护的代码。
模式匹配虽然强大,但在使用时,如果不了解其执行顺序和一些潜在的“坑”,可能会导致意料之外的行为。我个人在实践中就遇到过一些情况,所以深入理解这些细节非常重要。
1. 模式的执行顺序
switch
switch
object data = 100;
string result = data switch
{
int i => "匹配到 int 类型", // 会匹配到这里
> 50 => "匹配到大于 50 的值", // 这行永远不会被匹配到,因为它在 int i 之后
_ => "其他"
};
Console.WriteLine(result); // 输出: 匹配到 int 类型在这个例子中,即使
100
> 50
int i
> 50
2. 编译器的穷尽性检查(Exhaustiveness Checking)
对于
switch
switch
// 假设有一个枚举
enum TrafficLight { Red, Yellow, Green }
TrafficLight light = TrafficLight.Red;
string action = light switch
{
TrafficLight.Red => "Stop",
// 如果这里缺少 Yellow 或 Green,编译器会警告甚至报错,因为它不是穷尽的
_ => "Proceed" // _ 模式可以作为捕获所有未显式处理情况的最终手段
};但需要注意的是,对于
object
_
3. when
when
int value = 15;
string category = value switch
{
int i when i < 10 => "小于10",
int i when i >= 10 && i < 20 => "10到19之间", // 会匹配到这里
int i => "大于等于20",
_ => "其他"
};
Console.WriteLine(category); // 输出: 10到19之间这里,
int i
when
when
int i when ...
4. null
模式匹配对
null
null
null
object? item = null;
string description = item switch
{
string s => "字符串", // 不会匹配null
int i => "整数", // 不会匹配null
null => "空值", // 专门匹配null
_ => "其他非空类型" // 匹配所有非null且未被前面模式匹配的类型
};
Console.WriteLine(description); // 输出: 空值如果你不显式处理
null
item
null
null
_
_
switch
System.Runtime.CompilerServices.SwitchExpressionException
5. 潜在的性能考量
虽然编译器对模式匹配进行了大量优化,但在极端复杂的模式组合下,尤其是涉及大量属性模式和
when
总而言之,模式匹配是C#语言的一个巨大进步,但理解其内在机制,特别是模式的评估顺序和穷尽性检查,能帮助我们写出更健壮、更可预测的代码。在遇到不符合预期的情况时,首先检查模式的顺序,往往能找到问题的根源。
以上就是C#的switch语句有哪些新特性?如何模式匹配?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号