C#的switch语句从诞生之初就用于多条件分支判断,随着版本更新,尤其是C# 7.0及后续版本的迭代,引入了模式匹配特性,彻底改变了传统switch仅能匹配常量值的局限,让分支判断的逻辑更加灵活高效。下面先介绍switch语句的核心新特性,再详细讲解模式匹配的具体用法。

C# switch语句的核心新特性
相比传统switch语句,新版switch主要新增了以下特性:
- 支持模式匹配,不再局限于常量值匹配,可匹配类型、属性、关系运算结果等
- 支持switch表达式,可省略case和break关键字,直接将匹配结果赋值给变量
- 支持弃元模式,使用下划线匹配任意不满足前面条件的值
- 支持逻辑运算符组合多个匹配条件,简化复杂判断逻辑
- 无需显式声明变量即可提取匹配到的数据,减少冗余代码
模式匹配的常见类型及用法
1. 类型模式
类型模式用于判断输入值的类型,匹配成功后可直接转换为对应类型使用,无需额外的类型转换操作。
// 定义一个基类和一个派生类
public class Animal { }
public class Dog : Animal { public string Name { get; set; } }
public class Cat : Animal { public int Age { get; set; } }
public string GetAnimalInfo(Animal animal)
{
// 类型模式匹配,判断animal的具体类型
switch (animal)
{
case Dog d:
return $"这是一只狗,名字是{d.Name}";
case Cat c:
return $"这是一只猫,年龄是{c.Age}";
case null:
return "输入的对象为空";
default:
return "未知动物类型";
}
}
2. 属性模式
属性模式可以在匹配类型的同时,进一步检查对象的属性是否符合条件,实现更精细的判断。
public class Order
{
public string Status { get; set; }
public decimal Amount { get; set; }
}
public string GetOrderLevel(Order order)
{
// 属性模式匹配,同时判断类型和属性值
switch (order)
{
case Order { Status: "已完成", Amount: > 1000 }:
return "大额已完成订单";
case Order { Status: "已完成" }:
return "普通已完成订单";
case Order { Status: "待支付" }:
return "待支付订单";
default:
return "其他状态订单";
}
}
3. 关系模式
关系模式使用关系运算符(>、<、>=、<=)判断数值是否符合范围条件,适合处理数值区间的分支逻辑。
public string GetScoreLevel(int score)
{
// 关系模式匹配数值范围
switch (score)
{
case >= 90:
return "优秀";
case >= 80:
return "良好";
case >= 60:
return "及格";
case < 60:
return "不及格";
default:
return "无效分数";
}
}
4. 逻辑模式
逻辑模式通过and、or、not逻辑运算符组合多个匹配条件,简化复杂判断的写法。
public string CheckNumber(int num)
{
// 逻辑模式组合多个条件
switch (num)
{
case > 0 and < 10:
return "1到9之间的正数";
case >= 10 and <= 100:
return "10到100之间的数";
case not (> 0):
return "负数或零";
default:
return "大于100的正数";
}
}
switch表达式的简化用法
C# 8.0引入的switch表达式可以进一步简化代码,省略case和break关键字,直接将匹配结果赋值给变量,语法更加简洁。
public string GetWeekDayName(int day)
{
// switch表达式写法,更简洁
string dayName = day switch
{
1 => "星期一",
2 => "星期二",
3 => "星期三",
4 => "星期四",
5 => "星期五",
6 => "星期六",
7 => "星期日",
_ => "无效的星期值" // 弃元模式匹配其他情况
};
return dayName;
}
使用注意事项
- 模式匹配的顺序很重要,更具体的匹配条件应该放在前面,避免被宽泛的条件覆盖
- switch表达式必须覆盖所有可能的情况,或者使用弃元模式处理剩余情况,否则会编译报错
- 类型模式匹配时如果输入可能为null,需要显式添加null的判断分支,避免空引用异常
- 逻辑模式中的
not运算符优先级较高,组合条件时如果需要可以先加括号明确逻辑