Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Tip
Эта статья является частью раздела "Основы" для разработчиков , которые уже знают хотя бы один язык программирования и учат C#. Начните с обзора сопоставления шаблонов , если вы не знакомы с шаблонами. Полные правила для поддерживаемых типов и языков см. в разделе шаблоны списков справочника по языку.
Фигура последовательности — это набор наблюдаемых свойств, необходимых шаблону. Эти свойства могут включать количество элементов, требования, записанные для каждого элемента или последовательности элементов в целом, и значения маркеров на определенных индексах. Например, форма может требовать ровно два элемента с элементом "Name" в позиции 0, либо первый маркер, последний маркер и непустую последовательность между ними.
Шаблон списка описывает фигуру, сочетая требование счетчика элементов с вложенными шаблонами на упорядоченных позициях. Он проверяет только требования, указанные в шаблоне: подпаттерн элемента проверяет соответствующий ему элемент, а шаблон среза может допускать или проверять последовательность элементов, которые в противном случае не были бы сопоставлены. Эти части можно использовать для сопоставления точных значений счетчика и маркеров, записи значений на фиксированных позициях, разрешить несовпадную середину или применить вложенный шаблон к этой середине.
Выберите шаблон списка, если тип входных данных во время компиляции предоставляет свойство Length или Count и индексированный доступ к элементам, который позволяет получать элемент по его позиции, как в input[index]. Массивы, List<T>, строки и спаны — распространённые примеры. Компилятор определяет соответствие требованиям на основе объявленного типа переменной, известного на этапе компиляции, поскольку он должен разрешить эти обязательные члены до запуска программы. Сам IEnumerable<T> интерфейс предоставляет перечисление вместо этих элементов, даже если объект среды выполнения является индексируемой коллекцией.
Шаблоны списков используют длину или количество элементов и доступ к элементам по индексу вместо перечисления. Для распространенных встроенных типов сопоставление может проверять только позиции, именованные шаблоном, а не выполнять итерацию по каждому элементу. Стоимость этих операций зависит от типа входных данных. Итерацию длинной коллекции может занять некоторое время, поэтому используйте цикл или LINQ, если решение требует проверки произвольного количества элементов, а не конкретных позиций.
Сопоставить точную форму
Следующий метод распознает заголовок двух столбцов:
static bool IsHeader(string[] columns) =>
columns is ["Name", "Score"];
Выражение columns — это входные данные шаблона.
["Name", "Score"] содержит два константных шаблона. Точный шаблон списка исключает шаблон среза, требует ровно двух элементов и применяет каждый вложенный шаблон к элементу в одном индексе. Этот шаблон описывает форму с точным количеством и двумя значениями-маркерами: "Name" с индексом 0 и "Score" с индексом 1. Вложенные шаблоны элементов являются необязательными: шаблон [] пустого списка описывает и соответствует последовательности без элементов.
Выберите шаблон списка, если шаблон сочетает количество элементов с требованиями к элементам в определённых позициях. Если имеет значение только количество элементов, шаблон свойств Count или Length, например items is { Count: 0 }, более прямо выражает это намерение.
Использовать отбрасываемое значение для сопоставления с любым значением элемента
Следующий метод считывает победителя и участника, финишировавшего третьим, из списка из трёх имён в порядке финиша:
static string GetAnnouncements(List<string> finishingOrder) =>
finishingOrder switch
{
[var winner, _, var thirdPlace] =>
$"Winner: {winner}; third place: {thirdPlace}",
_ => "A complete three-runner result isn't available"
};
Шаблоны var winner и var thirdPlace каждый объявляют переменную. При совпадении шаблона списка C# назначает соответствующее значение элемента в этой позиции соответствующей переменной, поэтому результат может использовать winner и thirdPlace. Шаблон отбрасывания _ принимает второй элемент и игнорирует его значение. Для этой структуры требуется ровно три элемента, причём первой и третьей позициям придаётся особое значение, но конкретные значения ни в одной позиции не требуются.
Выберите эту форму, если фиксированные позиции имеют стабильное значение. Используйте цикл или LINQ, если необходимо проверить произвольное количество элементов, преобразовать последовательность, выполнить поиск по нему или выполнить агрегирование.
Разрешить оставшиеся элементы с шаблоном среза
В этом упрощённом примере командная строка может начинаться с --verbose, содержать другие аргументы и, как предполагается, заканчиваться именем входного файла. Следующий метод распознает фигуры с именем файла в последней позиции и записывает это значение:
static string GetInputFile(string[] arguments) =>
arguments switch
{
["--verbose", .., var fileName] => $"Verbose processing: {fileName}",
[.., var fileName] => $"Processing: {fileName}",
[] => "No input file was provided"
};
..
допускает наличие нуля или более оставшихся элементов между шаблонами первого и последнего элементов. Шаблон списка может содержать не более одного шаблона среза. Первая переключительная рука описывает фигуру с по крайней мере двумя элементами: маркером "--verbose" по индексу 0, именем файла в последней позиции и любым количеством несовпаденных аргументов между ними. Автономный срез не проверяет эти средние аргументы. Вторая ветвь принимает любой непустой шаблон и связывает его с последним элементом, а пустой шаблон обрабатывает последовательность, не содержащую элементов.
Срез может отображаться в начале, середине или конце шаблона списка. Используйте его, если последовательность переменной длины является частью фигуры, но только окружающие позиции нуждаются в тестах элементов. Используйте обычную итерацию, когда нужно обработать каждый элемент.
Применение шаблона к срезу
Вы можете применить другой шаблон к части, соответствующей ... Следующий метод проверяет, начинается ли массив с "BEGIN", заканчивается "END"и имеет хотя бы один элемент между ними:
static bool HasContent(string[] entries) =>
entries is ["BEGIN", .. { Length: > 0 }, "END"];
Внешний шаблон сначала требует наличия маркера "BEGIN" в позиции с индексом 0 и маркера "END" в последней позиции. Затем шаблон свойства { Length: > 0 } добавляет требование к последовательности, сопоставленной со срезом: последовательность должна содержать как минимум один элемент. Вместе эти требования описывают полную форму. Шаблон не проверяет значения элементов внутри среза.
Используйте подшаблон среза только тогда, когда сама средняя часть требует проверки или захвата. Если только элементы границы имеют значение, обычный .. проще.