列表与元组模式
解构集合。
列表与元组模式 是 CoddyKit 上的免费 C# Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C# Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C# Academy 课程共包含 4 节课。
元组模式
元组模式通过将多个值放在括号中,一次匹配这些值。每个位置都由自己的子模式进行匹配。
它非常适合处理依赖多个输入的判断,例如小型状态机或石头剪刀布裁判,并且可以全部放在同一个 switch 中。
int x = 0, y = 5;
string quadrant = (x, y) switch
{
(0, 0) => "origin",
(0, _) => "y-axis",
(_, 0) => "x-axis",
_ => "plane"
};
System.Console.WriteLine(quadrant);可运行的元组 Switch
元组模式可以让决策表更易读。这里使用两个布尔值来选择操作。
每个分支都会列出一个元组模式,某个位置上的丢弃符号 _ 表示该位置可以是任意值。最后的 _ 分支会覆盖其余情况。
using System;
class Program {
static string Move(bool fwd, bool turn) => (fwd, turn) switch {
(true, false) => "straight",
(true, true) => "curve",
(false, true) => "spin",
_ => "stop"
};
static void Main() => Console.WriteLine(Move(true, true));
}在元组中绑定值
元组模式中的位置可以捕获值。(0, var y) 会在第一个项目为 0 时匹配,并将第二个项目绑定到 y。
然后,您可以在分支结果或 when 保护条件中使用绑定的变量,从而在一个步骤中同时完成匹配和提取。
var point = (0, 7);
string r = point switch
{
(0, var y) => $"on y-axis at {y}",
(var x, 0) => $"on x-axis at {x}",
_ => "elsewhere"
};
System.Console.WriteLine(r);列表模式
列表模式根据数组和列表中的元素进行匹配,使用方括号书写:[1, 2, 3]。只有长度以及每个元素的模式都匹配时,整体才会匹配。
列表模式在 C# 11 中引入,可以直接根据序列形状进行分支,而不必手动检查长度和索引。
int[] data = { 1, 2, 3 };
string shape = data switch
{
[] => "empty",
[_] => "one",
[_, _] => "two",
_ => "many"
};
System.Console.WriteLine(shape);匹配精确元素
列表模式可以匹配每个位置上的特定值。[1, 2, 3] 只会匹配这个完全相同的三元素序列。
您可以自由混合使用常量和丢弃符号:[1, _, 3] 会匹配长度为三、以 1 开头并以 3 结尾的列表,而忽略中间元素。
using System;
class Program {
static void Main() {
int[] a = { 1, 9, 3 };
bool ok = a is [1, _, 3];
Console.WriteLine(ok);
}
}切片模式
切片模式 .. 可以在一个位置匹配任意数量的元素(包括零个)。一个列表模式最多只能包含一个切片。
[1, .., 9] 会匹配任何以 1 开头、以 9 结尾的列表,无论中间是什么内容。这非常适合检查 head 和 tail。
int[] nums = { 1, 4, 5, 9 };
string r = nums switch
{
[1, .., 9] => "1..9 bookends",
_ => "other"
};
System.Console.WriteLine(r);捕获切片
您可以使用 var 将切片中跳过的元素捕获到一个变量中:[first, .. var rest]。
捕获的部分本身就是一个由匹配类型构成的数组或列表,因此您可以解构出 head 元素,并保留 tail 以便进一步处理。
using System;
class Program {
static void Main() {
int[] xs = { 10, 20, 30, 40 };
if (xs is [var head, .. var tail])
Console.WriteLine($"{head} then {tail.Length} more");
}
}绑定边界元素
您可以在切片两端同时进行绑定:[var first, .., var last] 会捕获第一个和最后一个项目,同时忽略中间部分。
对于只关注边界的序列,这种写法非常简洁,例如验证路线是否从已知点开始并在已知点结束。
using System;
class Program {
static void Main() {
string[] route = { "A", "B", "C", "D" };
if (route is [var start, .., var end])
Console.WriteLine($"{start} -> {end}");
}
}带子模式的列表模式
列表中的每个位置都可以使用任意模式,包括关系模式和逻辑模式。[> 0, > 0] 会匹配一个包含两个正数的双元素列表。
这种方式将完整的模式工具箱组合到序列匹配中,让您可以在一个表达式中同时验证形状和内容。
int[] pair = { 3, 8 };
string r = pair switch
{
[> 0, > 0] => "both positive",
[_, _] => "mixed",
_ => "wrong size"
};
System.Console.WriteLine(r);嵌套元组和列表
元组模式和列表模式可以彼此嵌套,也可以嵌套在属性模式中。元组中的一个位置可以包含列表模式,反之亦然。
这样,您可以在一个表达式中匹配复杂的结构化数据,例如带标签的序列,而不必编写多个嵌套检查。
using System;
class Program {
static void Main() {
(string, int[]) record = ("primes", new[]{ 2, 3 });
string r = record switch {
("primes", [2, ..]) => "starts with 2",
_ => "other"
};
Console.WriteLine(r);
}
}列表模式的要求
列表模式适用于任何同时具备可计数和可索引能力的类型:它需要具有 Length 或 Count 属性以及索引器。数组、List<T> 和字符串都符合要求。
此外,要捕获切片,还需要切片方法或范围索引器。大多数内置集合都开箱即用地支持这两者。
string s = "cat";
bool isCat = s is ['c', 'a', 't'];
System.Console.WriteLine(isCat);快速检查
测试您对列表模式和元组模式的理解。
回顾
元组模式使用括号匹配多个值;列表模式使用方括号匹配序列形状,其中 .. 表示切片,并且可以通过 var 捕获中间部分。
每个位置都可以接受任意子模式,并且可以自由嵌套。列表模式要求类型同时具备可计数和可索引能力。现在,您已经掌握了完整的 C# 模式工具箱。
常见问题解答
「列表与元组模式」课时是免费的吗?
是的 — 「列表与元组模式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C# Academy 课程的其余内容,请升级到 CoddyKit PRO。 C# Academy 课程共包含 4 节课。
「列表与元组模式」这节课中我会学到什么?
解构集合。 你通过在浏览器中直接运行的动手代码来练习 C# Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C# Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C# Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「列表与元组模式」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C# Academy 课中编写并运行代码吗?
能。每节 C# Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- switch 表达式
- 类型与属性模式
- 关系模式与逻辑模式
- 列表与元组模式