类型模式
object obj = "hello";
// is + 模式
if (obj is string s)
{
Console.WriteLine(s.Length); // s 已经是 string 类型,可直接用
}
// 老写法(不推荐)
if (obj is string)
{
var s = (string)obj; // 多此一举
Console.WriteLine(s.Length);
}
is X x 同时检查类型 + 声明变量。
switch 表达式(C# 8+)
string description = obj switch
{
int n => $"integer {n}",
string s => $"string '{s}'",
null => "null",
_ => $"something else: {obj.GetType().Name}",
};
返回值、模式紧凑、穷举性检查(漏分支编译器告警)。
属性模式
record class Person(string Name, int Age, string City);
string Classify(Person p) => p switch
{
{ Age: < 18 } => "未成年",
{ Age: >= 65 } => "老年",
{ Age: >= 18 and < 65, City: "Beijing" } => "北漂",
{ Age: >= 18 and < 65 } => "中青年",
_ => "未知",
};
{ Property: pattern } 检查属性值匹配。嵌套也行:
{ Address: { City: "Beijing" } }
// 或简写(C# 10+)
{ Address.City: "Beijing" }
关系模式(C# 9+)
x switch
{
< 0 => "负",
0 => "零",
> 0 and < 10 => "小正数",
>= 10 and <= 100 => "中等",
> 100 => "大",
}
< > <= >= == 直接用作模式。
逻辑模式
n switch
{
1 or 2 or 3 => "小",
not 0 => "非零",
> 0 and < 10 => "1-9",
}
and / or / not 组合。
列表模式(C# 11+)
int[] arr = { 1, 2, 3 };
string desc = arr switch
{
[] => "空",
[_] => "一个元素",
[1, ..] => "1 开头",
[.., 3] => "3 结尾",
[1, _, 3] => "1 ? 3",
[var first, ..] => $"开头是 {first}",
};
.. 是"任意个"占位;var x 捕获元素。
解构模式
record class Point(int X, int Y);
string Quadrant(Point p) => p switch
{
(0, 0) => "原点",
(> 0, > 0) => "第一象限",
(< 0, > 0) => "第二象限",
var (x, y) when x == y => $"对角线 ({x},{y})",
_ => "其他",
};
(x, y) 解构(record / tuple / 自定义 Deconstruct)。
var 模式 + when
x switch
{
var n when n > 0 && n < 10 => $"小正数 {n}",
var n => $"其他 {n}",
}
var n 永远匹配 + 捕获,配 when 加额外条件。
实战:状态机
record class Loading;
record class Loaded(string Data);
record class Failed(string Error);
object state = ...;
string Display(object state) => state switch
{
Loading => "加载中...",
Loaded(string data) => $"数据: {data}",
Failed(string err) => $"错误: {err}",
_ => "未知",
};
配合 record 解构 + 类型模式——和 Rust / Scala 的代数数据类型很接近。
不要忘 _ 兜底
DayOfWeek day = DayOfWeek.Monday;
string msg = day switch
{
DayOfWeek.Monday => "周一",
DayOfWeek.Tuesday => "周二",
// 编译警告:可能没匹配到 Wednesday-Sunday
};
穷举性检查——枚举漏分支编译器警告。要么列全所有分支,要么 _ => default;。
switch 表达式 vs switch 语句
// 表达式:返回值
var msg = x switch { ... };
// 语句:执行代码块
switch (x)
{
case 1:
DoSomething();
break;
case 2 or 3:
DoOther();
break;
}
新代码优先表达式——简洁、强类型、强检查。语句版本只在分支需要多语句副作用时用。
模式匹配 vs if 链
// ❌ if-else 链
if (obj is int n) ...
else if (obj is string s) ...
else if (obj is null) ...
else ...
// ✅ switch 表达式
var result = obj switch
{
int n => ...,
string s => ...,
null => ...,
_ => ...,
};
3+ 分支用 switch;2 个用 if 也行。
→ 下一篇 可空引用类型