Полное руководство по языку программирования С# 14 и платформе .NET 10 / Pattern matching

Паттерны списков

Начальный ⏱ 5 мин чтения 👁 2 🕓 обновлено 11.08.2026

Паттерны списков (list pattern) позволяют сопоставлять выражения со списками и массивами. Данный паттерн пока доступен начиная с версии C# 11.

Полное совпадение с массивом/списком:


Console.WriteLine(GetNumber(new[] { 1, 2, 3, 4, 5 }));  // 1
Console.WriteLine(GetNumber(new[] { 1, 2}));            // 3
Console.WriteLine(GetNumber(new int[] {}));             // 4
Console.WriteLine(GetNumber(new[] { 1, 2, 5 }));        // 5

int GetNumber(int[] values)=> values switch
{
        [1, 2, 3, 4, 5] => 1,
        [1, 2, 3] => 2,
        [1, 2] => 3,
        [] => 4,
        _ => 5
};

Аналогично вместо массивов можно применять списки:


List<int> numbers = new List<int>{1, 2, 3};

Console.WriteLine(GetNumber(numbers));  // 2

int GetNumber(List<int> values) => values switch
{
    [1, 2, 3, 4, 5] => 1,
    [1, 2, 3] => 2,
    [1, 2] => 3,
    [] => 4,
    _ => 5
};

Аналогичным образом паттерны списков можно использовать в конструкции if:


int[] numbers = { 1, 2, 3, 4, 5 };
if(numbers is [1, 2, 3, 4, 5])
{
    Console.WriteLine("[1, 2, 3, 4, 5]");
}

Подстановка _

С помощью паттерна _ можно обозначить одиночный элемент, который имеет любое значение. Например, паттерн [2, _, 5] соответствует любому массиву из трех элементов, в котором между 2 и 5 располагается произвольное значение. А массив [_, _] соответствует любому массиву из двух произвольных элементов

Несколько примеров:


Console.WriteLine(GetNumber(new[] { 2, 3, 5}));       // 1
Console.WriteLine(GetNumber(new[] { 2, 4, 6 }));      // 2
Console.WriteLine(GetNumber(new[] { 1, 2, 5 }));      // 3
Console.WriteLine(GetNumber(new[] { 1, 2, 3}));      // 4
Console.WriteLine(GetNumber(new int[] { }));         // 5

int GetNumber(int[] values) => values switch
{
    [2, _, 5] => 1,
    [2, _, _] => 2,
    [_, _, 5] => 3,
    [_, _, _] => 4,
    _ => 5
};

slice-паттерн

Для передачи произвольного количества элементов массива/списка применяется slice-паттерн ... Например, паттерн [1, 2, .., 5] соответствует массиву, в который начинается на 1, за которым идет 2. А последний элемент в массиве - 5. При этом между 2 и 5 может располагаться произвольное количество произвольных целых чисел. То есть паттерн [1, 2, .., 5] будет соответствовать таким массивам как


int[] arr1 = {  1, 2, 3, 4, 5 };
int[] arr2 = { 1, 2, 5 };
int[] arr3 = { 1, 2, 66, 77, 88, 5 };

С помощью паттерна .. можно задавать произвольное количество элементов как в начале, так и в конце массива/списка. Например, паттерн [2,..] представляет массив, который начинается на 2. А паттерн [.., 5] представляет массив, который заканчивается элементом 5. Паттерн [..] представляет массив, который содержит произвольное количество элементов. Например:


Console.WriteLine(GetNumber(new[] { 2, 5 }));           // 1
Console.WriteLine(GetNumber(new[] { 2, 3, 4, 5 }));     // 1

Console.WriteLine(GetNumber(new[] { 2}));               // 2
Console.WriteLine(GetNumber(new[] { 2, 3, 4}));         // 2

Console.WriteLine(GetNumber(new[] {3, 4, 5}));          // 3
Console.WriteLine(GetNumber(new[] { 5 }));              // 3

Console.WriteLine(GetNumber(new int[] {  }));           // 4
Console.WriteLine(GetNumber(new[] { 1 }));              // 4
Console.WriteLine(GetNumber(new[] { 1, 2, 3 }));        // 4

int GetNumber(int[] values)=> values switch
{
    [2, .., 5] => 1,    // если первый элемент - 2, а последний - 5
    [2,..] => 2,        // если первый элемент - 2
    [.., 5] => 3,       // если последний элемент - 5
    [..] => 4          // произвольное количество элементов
};

slice-паттерн можно сочетать с символов подстановки _, например:


int GetNumber(int[] values) => values switch
{
    [_, .., _] => 1,
    [..] => 2
};

В данном случае паттерн [_, .., _] предполагает массив, который состоит как минимум из двух произвольных элементов, и между первым и последним элементром может находиться произвольное количество других элементов:


Console.WriteLine(GetNumber(new[] { 1, 2, 3, 4}));   // 1
Console.WriteLine(GetNumber(new[] { 1, 2, 3}));     // 1
Console.WriteLine(GetNumber(new[] { 1, 2}));        // 1
Console.WriteLine(GetNumber(new[] { 1 }));          // 2
Console.WriteLine(GetNumber(new int[] { }));       // 2

int GetNumber(int[] values) => values switch
{
    [_, .., _] => 1,
    [..] => 2
};

Получение элементов в переменные

Отдельные значения массива/списка можно получить в переменные, например:


int[] numbers = { 2, 3, 5 };
if(numbers is [var first, var second, .., var last])
{
    Console.WriteLine($"first: {first}, second: {second}  last: {last}");
}

В данном случае получаем первый элемент массива в переменную first, второй элемент - в переменную second, а последний элемент - в переменную last.

Пример с различными массивами:


Console.WriteLine(GetData(new[] { 1, 2, 3 }));        // First: 1  Second: 2  Last: 3
Console.WriteLine(GetData(new[] { 2, 4, 6, 8 }));    // First: 2  Second: 4  Last: 8
Console.WriteLine(GetData(new[] { 1, 2 }));          // Array has less than 3 elements

string GetData(int[] values) => values switch
{
    [var first, var second, .., var last] => $"First: {first}  Second: {second}  Last: {last}",
    [..] => "Array has less than 3 elements"
};

В данном случае получаем первый элемент массива в переменную first, второй элемент - в переменную second, а последний элемент - в переменную last.

При этом значения, которые проектируются на паттерн .., также можно получить в переменную. Например, в паттерне [2, .. var middle, 5] элементы, которые проектируются на .., можно передаются в переменную middle. Несколько примеров:


Console.WriteLine(GetSlice(new[] { 2, 3, 4, 5}));       // Middle: 3, 4
Console.WriteLine(GetSlice(new[] { 2, 4, 6, 8 }));      // End: 4, 6, 8
Console.WriteLine(GetSlice(new[] { 1, 2, 3, 5 }));      // Start: 1, 2, 3
Console.WriteLine(GetSlice(new[] { 1, 2, 3, 4 }));      // All: 1, 2, 3, 4
Console.WriteLine(GetSlice(new int[] { }));             // All: 

string GetSlice(int[] values) => values switch
{
    [2, .. var middle, 5] => $"Middle: {string.Join(", ", middle)}",
    [2, .. var end] => $"End: {string.Join(", ", end)}",
    [.. var start, 5] => $"Start: {string.Join(", ", start)}",
    [.. var all] => $"All: {string.Join(", ", all)}"
};

Свойства коллекций

Стоит отметить, что, поскольку массивы и списки - обычные классы C#, которые имеют свойства, то для них мы также можем применять паттерн свойств. Объединение паттерна свойств и паттерна списков позволяет упростить решение некоторых задач. Например, у нас есть задача: если массив имеет три элемента, то разложить его на три переменных:


int[] numbers = { 2, 3, 5 };
if(numbers is { Length:3} and [var first, var second, var third])
{
    Console.WriteLine($"first: {first}, second: {second}  third: {third}");
}

Проверь себя

📋 Тест по теме «Паттерны списков» Тест по теме

Практические задания

Лёгкое Ручная проверка Заполните пропуск в коде (1)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

_____.WriteLine(GetNumber(new[] { 1, 2, 3, 4, 5 }));  // 1
Console.WriteLine(GetNumber(new[] { 1, 2}));            // 3
Console.WriteLine(GetNumber(new int[] {}));             // 4
Console.WriteLine(GetNumber(new[] { 1, 2, 5 }));        // 5

int GetNumber(int[] values)=> values switch
{
        [1, 2, 3, 4, 5] => 1,
        [1, 2, 3] => 2,
        [1, 2] => 3,
        [] => 4,
        _ => 5
};
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (2)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

List<int> _____ = new List<int>{1, 2, 3};

Console.WriteLine(GetNumber(numbers));  // 2

int GetNumber(List<int> values) => values switch
{
    [1, 2, 3, 4, 5] => 1,
    [1, 2, 3] => 2,
    [1, 2] => 3,
    [] => 4,
    _ => 5
};
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (3)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

int[] numbers = { 1, _____, 3, 4, 5 };
if(numbers is [1, 2, 3, 4, 5])
{
    Console.WriteLine("[1, 2, 3, 4, 5]");
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (4)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

Console.WriteLine(GetNumber(_____[] { 2, 3, 5}));       // 1
Console.WriteLine(GetNumber(new[] { 2, 4, 6 }));      // 2
Console.WriteLine(GetNumber(new[] { 1, 2, 5 }));      // 3
Console.WriteLine(GetNumber(new[] { 1, 2, 3}));      // 4
Console.WriteLine(GetNumber(new int[] { }));         // 5

int GetNumber(int[] values) => values switch
{
    [2, _, 5] => 1,
    [2, _, _] => 2,
    [_, _, 5] => 3,
    [_, _, _] => 4,
    _ => 5
};
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (5)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

int[] arr1 = {  1, 2, 3, _____, 5 };
int[] arr2 = { 1, 2, 5 };
int[] arr3 = { 1, 2, 66, 77, 88, 5 };
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (1)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

_____.WriteLine(GetNumber(new[] { 1, 2, 3, 4, 5 }));  // 1
_____.WriteLine(GetNumber(new[] { 1, 2}));            // 3
Console.WriteLine(GetNumber(new int[] {}));             // 4
Console.WriteLine(GetNumber(new[] { 1, 2, 5 }));        // 5

int GetNumber(int[] values)=> values switch
{
        [1, 2, 3, 4, 5] => 1,
        [1, 2, 3] => 2,
        [1, 2] => 3,
        [] => 4,
        _ => 5
};
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (2)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

List<int> numbers = new List<int>{_____, 2, 3};

Console.WriteLine(GetNumber(numbers));  // 2

int GetNumber(List<int> _____) => values switch
{
    [1, 2, 3, 4, 5] => 1,
    [1, 2, 3] => 2,
    [1, 2] => 3,
    [] => 4,
    _ => 5
};
Войдите, чтобы отправить решение
Среднее Ручная проверка Расставьте строки кода в правильном порядке
+20 XP

Строки кода из примера этого урока перемешаны. Впишите их в правильном порядке, каждую строку — с новой строки.

{
    Console.WriteLine("[1, 2, 3, 4, 5]");
}
int[] numbers = { 1, 2, 3, 4, 5 };
if(numbers is [1, 2, 3, 4, 5])
Войдите, чтобы отправить решение
Сложное Ручная проверка Объясните и модифицируйте пример из урока «Паттерны списков»
+30 XP

Опишите своими словами, что делает приведённый пример кода из урока «Паттерны списков», и предложите одно осмысленное изменение (например, другое входное значение или дополнительное условие). Приведите итоговый код.

Console.WriteLine(GetNumber(new[] { 1, 2, 3, 4, 5 }));  // 1
Console.WriteLine(GetNumber(new[] { 1, 2}));            // 3
Console.WriteLine(GetNumber(new int[] {}));             // 4
Console.WriteLine(GetNumber(new[] { 1, 2, 5 }));        // 5

int GetNumber(int[] values)=> values switch
{
        [1, 2, 3, 4, 5] => 1,
        [1, 2, 3] => 2,
        [1, 2] => 3,
        [] => 4,
        _ => 5
};
Войдите, чтобы отправить решение
Сложное Ручная проверка Найдите потенциальную проблему в коде урока «Паттерны списков»
+30 XP

Изучите приведённый фрагмент кода и опишите, при каких входных данных или условиях он может сработать не так, как ожидается (граничный случай, отсутствие проверки и т.п.). Предложите исправленный вариант.

List<int> numbers = new List<int>{1, 2, 3};

Console.WriteLine(GetNumber(numbers));  // 2

int GetNumber(List<int> values) => values switch
{
    [1, 2, 3, 4, 5] => 1,
    [1, 2, 3] => 2,
    [1, 2] => 3,
    [] => 4,
    _ => 5
};
Войдите, чтобы отправить решение
Мини-проект Ручная проверка Мини-проект по теме «Паттерны списков»
+50 XP

Соберите небольшую программу, которая последовательно демонстрирует ключевые идеи урока. Программа должна быть рабочей и содержать минимум два самостоятельно написанных фрагмента, а не просто копию примера из урока.

Войдите, чтобы отправить решение
Домашнее задание Ручная проверка Домашнее задание по теме «Паттерны списков»
+25 XP

Напишите собственную небольшую программу, применяющую материал темы «Паттерны списков». Используйте не менее одной конструкции, показанной в примерах урока. Прикрепите код решения и краткое описание того, что он делает.

Войдите, чтобы отправить решение

Обсуждение (0)

Войдите, чтобы оставить комментарий.