List and Tuple Patterns
Destructure collections.
List and Tuple Patterns is a free C# Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C# Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Tuple Patterns
A tuple pattern matches several values at once by wrapping them in parentheses. Each position is matched by its own sub-pattern.
This is ideal for decisions that depend on multiple inputs, like a small state machine or a rock-paper-scissors judge, all in one 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);A Runnable Tuple Switch
Tuple patterns make decision tables readable. Here two booleans pick an action.
Each arm lists a tuple pattern, and the discard _ in a position means that slot can be anything. The final _ arm covers the rest.
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));
}Binding Inside Tuples
Positions in a tuple pattern can capture values. (0, var y) matches when the first item is 0 and binds the second to y.
You can then use the bound variable in the arm result or in a when guard, mixing matching and extraction in one step.
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);List Patterns
A list pattern matches arrays and lists by their elements, written with square brackets: [1, 2, 3]. It matches when the length and each element pattern agree.
Introduced in C# 11, list patterns let you branch on sequence shape directly without manual length and index checks.
int[] data = { 1, 2, 3 };
string shape = data switch
{
[] => "empty",
[_] => "one",
[_, _] => "two",
_ => "many"
};
System.Console.WriteLine(shape);Matching Exact Elements
List patterns can match specific values per position. [1, 2, 3] matches only that exact three-element sequence.
Mix constants and discards freely: [1, _, 3] matches a length-three list that starts with 1 and ends with 3, ignoring the middle.
using System;
class Program {
static void Main() {
int[] a = { 1, 9, 3 };
bool ok = a is [1, _, 3];
Console.WriteLine(ok);
}
}The Slice Pattern
The slice pattern .. matches any number of elements (including zero) in one position. A list pattern may contain at most one slice.
[1, .., 9] matches any list that starts with 1 and ends with 9, whatever lies between. This is great for head and tail checks.
int[] nums = { 1, 4, 5, 9 };
string r = nums switch
{
[1, .., 9] => "1..9 bookends",
_ => "other"
};
System.Console.WriteLine(r);Capturing a Slice
The slice can capture the skipped elements into a variable using var: [first, .. var rest].
The captured portion is itself an array or list of the matched type, letting you destructure a head element and keep the tail for further processing.
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");
}
}Binding Edge Elements
You can bind both ends around a slice: [var first, .., var last] captures the first and last items while ignoring the middle.
This is concise for sequences where only the boundaries matter, such as validating that a route starts and ends at known points.
using System;
class Program {
static void Main() {
string[] route = { "A", "B", "C", "D" };
if (route is [var start, .., var end])
Console.WriteLine($"{start} -> {end}");
}
}List Patterns with Sub-Patterns
Each list position can use any pattern, including relational and logical ones. [> 0, > 0] matches a two-element list of positives.
This composes the full pattern toolbox into sequence matching, so you can validate both shape and content in a single expression.
int[] pair = { 3, 8 };
string r = pair switch
{
[> 0, > 0] => "both positive",
[_, _] => "mixed",
_ => "wrong size"
};
System.Console.WriteLine(r);Nesting Tuples and Lists
Tuple and list patterns nest inside each other and inside property patterns. A tuple position can hold a list pattern and vice versa.
This lets you match complex structured data, like a labeled sequence, in one expression rather than several nested checks.
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);
}
}Requirements for List Patterns
List patterns work on any type that is countable and indexable: it needs a Length or Count property and an indexer. Arrays, List<T>, and strings qualify.
Slice capture additionally needs a slice method or range indexer. Most built-in collections support both out of the box.
string s = "cat";
bool isCat = s is ['c', 'a', 't'];
System.Console.WriteLine(isCat);Quick Check
Test your understanding of list and tuple patterns.
Recap
Tuple patterns match multiple values in parentheses; list patterns match sequence shape in brackets, with .. as a slice that can capture the middle via var.
Positions accept any sub-pattern and nest freely. List patterns need a countable, indexable type. You now command the full C# pattern toolbox.
Frequently asked questions
Is the “List and Tuple Patterns” lesson free?
Yes — the full text of “List and Tuple Patterns” is free to read here on the web, and the C# Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C# Academy course, upgrade to CoddyKit PRO.
What will I learn in “List and Tuple Patterns”?
Destructure collections. You practise C# Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start C# Academy?
No prior experience is required. C# Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “List and Tuple Patterns” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this C# Academy lesson?
Yes. Every C# Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- switch Expressions
- Type and Property Patterns
- Relational and Logical Patterns
- List and Tuple Patterns