How it works
A list pattern checks the shape and selected contents of a sequence-like value. The first arm requires a leading one and at least one more element. It captures that second element in second, while the slice pattern accepts whatever follows. The three-element array therefore produces second:8.
The next arm recognizes exactly one element equal to one. It does not match the first arm because the required second element is missing. The empty list pattern recognizes the zero-length array. Ordering matters because a switch expression chooses its first matching arm, so more general patterns should not accidentally hide a specific case.
The shape check avoids reading an index before proving that index exists. Without it, code might test row[0] or row[1] on an empty or short array and throw. A pattern can combine length requirements, constant values, and captured values in one visible condition, making small structured protocols easier to inspect.
This is a matching feature, not a general streaming query. Use it on types that support the required list-pattern operations, such as arrays in this sample. An arbitrary IEnumerable may represent an expensive or infinite computation and should not be treated as though it were a small indexed array.
Practice by adding an arm for [0, ..] and another for exactly two elements whose first value is one. Place the new arms deliberately and test arrays of lengths zero through four. Explain which cases require exactly a length and which accept a minimum length followed by a remainder.
Then apply a property guard to the captured second value, returning a different label when it is negative. Keep the shape decision separate from the business validation when that makes the code clearer. The goal is an explicit, testable contract for accepted inputs rather than a dense pattern that conceals the meaning of each case.
A working example
using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
foreach (int[] row in new[] { new[] { 1, 8, 9 }, new[] { 1 }, Array.Empty<int>() }) {
string label = row switch {
[1, var second, ..] => $"second:{second}",
[1] => "single",
[] => "empty",
_ => "other"
};
Console.WriteLine(label);
}
Expected output
second:8 single empty
The slice pattern .. accepts the remaining elements after the required prefix.