C# 11 引入的 列表模式(List Patterns) 是对模式匹配能力的重要增强,它让你能更自然、更安全地解构数组、只读集合(如
IReadOnlyList<t></t>)、
Span<t></t>等支持索引和长度的序列类型,而不仅限于固定长度的元组或对象。
什么是列表模式?
列表模式允许你在
switch表达式或
is检查中,用类似数组字面量的语法来匹配序列结构。核心是三个新语法元素: 位置匹配:如
[1, 2, 3]匹配长度为 3 且各元素值严格相等的序列 通配符
_:跳过某个位置的值,不绑定变量 切片模式
..:匹配任意长度的子序列(零个或多个元素),可放在开头、中间或结尾
基础用法:匹配常见结构
假设你有一个整数数组:
int[] numbers = [1, 2, 3, 4, 5];
你可以这样写模式匹配:
numbers is [1, _, _, _, 5]→
true(首尾固定,中间任意)
numbers is [1, .., 5]→
true(开头是 1,结尾是 5,中间任意长度)
numbers is [.., 4, 5]→
true(末尾两个是 4 和 5)
numbers is [1, 2, ..]→
true(前两个是 1 和 2,后面不管多少都行)
numbers is [..rest]→
true,且
rest绑定为整个数组(类型是
int[])
结合变量绑定与类型检查
列表模式支持在匹配同时提取值并声明变量,甚至做类型转换:
if (obj is int[] [1, var x, ..])→ 匹配以 1 开头、第二个元素赋给
x、后面任意的
int[]
if (list is IList<string> [..first, "done"])</string>→ 匹配以
"done"结尾的字符串列表,
first是除最后一个外的所有元素(类型为
IList<string></string>) 注意:
..左右不能同时省略变量名,即
[..]合法(匹配任意序列),但
[..x..]不合法
实际应用场景举例
列表模式特别适合处理有结构约定的数据序列:
解析命令行参数:判断args是否为
["build", "--target", var target]或
["run", ..]HTTP 路由匹配:把路径段
segments is ["api", "users", var id]提取用户 ID 协议帧解析:如 WebSocket 帧头
bytes is [0x81, ..payload]判断是否为文本帧并提取负载 避免手动
.Length和索引检查,让代码更声明式、更少出错
基本上就这些。列表模式不是万能的(不支持非索引集合如
HashSet<t></t>),但它让 C# 对“序列结构”的表达力上了一个台阶,配合
switch表达式,写出的逻辑更清晰、更健壮。
