Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Tip
Эта статья является частью раздела "Основы" для разработчиков , которые уже знают хотя бы один язык программирования и учат C#. Начните с обзора сопоставления шаблонов , если вы не знакомы с шаблонами. Полные языковые правила см. в шаблонах свойств и позиционных шаблонах в справочнике по языку.
Шаблоны свойств и позиционные шаблоны оба проверяют части значения. Разница заключается в том, как они определяют эти части:
- Шаблон свойства указывает свойства или поля, которые нужно проверять.
- Позиционный шаблон определяет значения по их порядку.
Деконструкция предоставляет упорядоченный набор значений компонентов. Кортеж уже имеет порядок элементов; см. деконструкцию кортежей. Для другого типа Deconstruct метод определяет, какие значения компонентов предоставляются и их порядок.
Сравнение имен и позиций
Следующий шаблон сопоставления по свойствам проверяет два именованных свойства погодного показания со значениями температуры в градусах по Цельсию:
static bool IsHotAndHumid(WeatherReading reading) =>
reading is { TemperatureC: > 30, HumidityPercent: > 70 };
sealed record WeatherReading(int TemperatureC, int HumidityPercent);
Следующий позиционный шаблон проверяет значение сигнала, после которого следует логическое значение:
static string GetCrossingInstruction(
PedestrianSignal signal, bool crossingIsClear) =>
(signal, crossingIsClear) switch
{
(PedestrianSignal.Walk, true) => "Cross now",
(PedestrianSignal.Walk, false) => "Wait for the crossing to clear",
_ => "Wait for the walk signal"
};
enum PedestrianSignal
{
Stop,
Walk
}
Шаблон свойства определяет входные данные по именам TemperatureC и HumidityPercent. Код пересечения создает кортеж из отдельных signal и crossingIsClear значений. Затем шаблон кортежа идентифицирует эти значения по порядку: сначала signal, а затем crossingIsClear. Позиционный шаблон здесь удачно подходит, поскольку этот только что созданный кортеж содержит всего два значения, и их порядок имеет однозначный смысл при принятии решения о пересечении.
Выберите шаблон свойств, когда имена участников помогают объяснить тест. Шаблоны свойств обычно более понятны для классов, структур и записей. Выберите позиционный шаблон, если порядок уже придаёт значениям очевидный смысл. Позиционные шаблоны наиболее полезны для кортежей, которые объединяют несколько связанных значений в одно значение с фиксированным порядком.
Следуйте вложенным входным данным в рекурсивных шаблонах
Свойства и позиционные шаблоны являются рекурсивными шаблонами: они применяют другой шаблон к каждому свойству, полю или расположению, которые они выбирают. Выбранное значение становится входными данными в вложенный шаблон.
reading Выражение IsHotAndHumid— это входные данные в шаблон свойств. C# вычисляет это выражение перед сопоставлением. Шаблон получает два значения из результирующего объекта:
- Реляционный шаблон
> 30проверяет значениеTemperatureC. - Реляционный шаблон
> 70проверяет значениеHumidityPercent.
Тест внешнего типа является необязательным, а предложения рекурсивных шаблонов могут быть пустыми. Например, шаблон { } пустого свойства соответствует любому вычисляемому значению, отличному от NULL.
Шаблоны свойств и позиционные шаблоны сопоставляются только с вычисленными значениями, отличными от NULL. Когда null входит в входной домен, выберите рекурсивный шаблон, который сначала проверяет значение, отличное от NULL:
static string DescribeNullableInput(object? value)
{
if (value is not { } nonNullValue)
{
return "No value";
}
return nonNullValue switch
{
DateTime => "Date",
string => "Text",
_ => "Another type"
};
}
Входное выражение — value. C# вычисляет это выражение, а шаблон свойства { } проверяет, что результирующее значение не равно null, перед его присваиванием переменной nonNullValue. Следующее выражение коммутатора может протестировать несколько возможных типов среды выполнения. Его DateTime и string шаблоны типов не имеют обозначения, так как метод должен определять только каждый тип, а не захватывать его значение.
Если предложения рекурсивных шаблонов содержат вложенные шаблоны, каждое выбранное свойство, поле или положение становится входными данными в вложенный шаблон.
Вы можете добавить тест типа перед фигурными скобками, когда входное выражение может создавать различные типы. Вы также можете использовать путь члена для тестирования вложенного свойства:
static string DescribeDate(object? value) =>
value switch
{
DateTime { Date.DayOfWeek:
DayOfWeek.Saturday or DayOfWeek.Sunday } => "Weekend date",
DateTime => "Weekday date",
null => "No date",
_ => "Not a date"
};
value — это входное выражение. C# сначала вычисляет это и проверяет, является ли полученное значение значением типа DateTime. Затем значение свойства Date используется как входные данные для обращения к члену DayOfWeek. Наконец, DayOfWeek значение становится входным в логический шаблон, который проверяет две константы. Сопоставление завершается успешно, если внешнее значение имеет указанный тип, и каждый объект, необходимый вдоль пути элемента, не имеет значения NULL.
Сравнение шаблонов с операторами ветвления
DescribeDate Предыдущий метод выражает четыре результата в виде шаблонов:
static string DescribeDate(object? value) =>
value switch
{
DateTime { Date.DayOfWeek:
DayOfWeek.Saturday or DayOfWeek.Sunday } => "Weekend date",
DateTime => "Weekday date",
null => "No date",
_ => "Not a date"
};
Следующий метод дает тот же результат с использованием последовательности императивных операторов ветвления:
static string DescribeDateWithBranches(object? value)
{
if (value is DateTime date)
{
if (date.DayOfWeek == DayOfWeek.Saturday ||
date.DayOfWeek == DayOfWeek.Sunday)
{
return "Weekend date";
}
return "Weekday date";
}
if (value is null)
{
return "No date";
}
return "Not a date";
}
Версия на основе шаблона сохраняет возможные результаты вместе, когда несколько ветвей проверяют тип и фигуру значения. Императивная версия делает каждую проверку и каждый шаг возврата явными. При одном условии обе формы могут выглядеть похоже. По мере роста числа связанных ветвей шаблоны могут упростить сравнение альтернативных вариантов.