Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Сопоставление шаблонов —
is
Используйте выражение, оператор switch и выражение коммутатора для сопоставления входного выражения с любым количеством характеристик. C# поддерживает несколько шаблонов, включая объявление, тип, константу, реляционную, свойство, список, вар и отмену. Вы можете объединить шаблоны с помощью логических ключевых слов логики and, orа также not.
Справочные документы по языку C# описывают последнюю выпущенную версию языка C#. Она также содержит начальную документацию по функциям в общедоступных предварительных версиях для предстоящего языкового выпуска.
Документация определяет любую функцию, впервые представленную в последних трех версиях языка или в текущих общедоступных предварительных версиях.
Совет
Чтобы узнать, когда функция впервые появилась в C#, ознакомьтесь со статьей об истории версий языка C#.
Сопоставление шаблонов поддерживают следующие выражения и операторы C#:
В этих конструкциях можно сравнить входное выражение с любым из следующих шаблонов:
- Шаблон объявления: проверьте тип выражения во время его выполнения и, если совпадение успешно, назначьте результат выражения заранее объявленной переменной.
- Шаблон типа: проверьте тип времени выполнения выражения.
- Шаблон констант: проверка того, что результат выражения равен указанной константе.
- Реляционные шаблоны: сравнивайте результат выражения с указанной константой.
- Логические шаблоны: проверка соответствия выражения логическому сочетанию шаблонов.
- Шаблон свойств: проверьте, соответствуют ли свойства или поля выражения вложенным шаблонам.
- Позиционный шаблон: деконструирует результат выражения и проверяет, соответствуют ли полученные значения вложенным шаблонам.
-
varшаблон: сопоставляет любое выражение и назначает результат объявленной переменной. - Шаблон отбрасывания: соответствует любому выражению.
- Шаблоны списка: проверьте, соответствует ли последовательность элементов соответствующим вложенным шаблонам.
Логические, свойства, позиционные и списковые шаблоны являются рекурсивными шаблонами. То есть, они могут содержать вложенные шаблоны.
Пример использования этих шаблонов для создания алгоритма на основе данных см. в руководстве. Использование сопоставления шаблонов для создания алгоритмов, управляемых типом и данными.
Шаблоны объявления и шаблоны типов
Используйте шаблоны объявлений и типов, чтобы проверить, совместим ли тип времени выполнения выражения с заданным типом. С помощью шаблона объявления можно также объявить новую локальную переменную. Если шаблон объявления соответствует выражению, переменная назначается преобразованной результату выражения, как показано в следующем примере:
object greeting = "Hello, World!";
if (greeting is string message)
{
Console.WriteLine(message.ToLower()); // output: hello, world!
}
Шаблон объявления с типом T соответствует выражению, если результат выражения не имеет значения NULL, и любое из следующих условий имеет значение true:
- Тип времени выполнения результата выражения имеет идентичное преобразование к
T. - Тип — это
Tтипref struct, и преобразование удостоверений из выраженияTв . - Тип результата выражения в среде выполнения является производным от типа
T, реализует интерфейсTили существует другое неявное преобразование ссылок из него вT. Это условие охватывает связи наследования и реализации интерфейса. В следующем примере показаны два случая, когда данное условие истинно:
В предыдущем примере при первом вызове методаvar numbers = new int[] { 10, 20, 30 }; Console.WriteLine(GetSourceLabel(numbers)); // output: 1 var letters = new List<char> { 'a', 'b', 'c', 'd' }; Console.WriteLine(GetSourceLabel(letters)); // output: 2 static int GetSourceLabel<T>(IEnumerable<T> source) => source switch { Array array => 1, ICollection<T> collection => 2, _ => 3, };GetSourceLabelпервый шаблон соответствует значению аргумента, так как тип этого аргумента (int[]) в среде выполнения является производным от типа Array. При втором вызове методаGetSourceLabelтип аргумента в среде выполнения (List<T>) не является производным от типа Array, но реализует интерфейс ICollection<T>. - Тип времени выполнения результата выражения — это тип значения, допускающего значение NULL , с базовым типом
Tи типом Nullable<T>.HasValuetrue. -
Преобразование упаковки или распаковки существует из типа результата выражения во время выполнения в тип
T, если выражение не является экземпляромref struct.
Шаблоны объявлений не учитывают определяемые пользователем преобразования или неявные преобразования диапазона.
В следующем примере показаны два последних условия:
int? xNullable = 7;
int y = 23;
object yBoxed = y;
if (xNullable is int a && yBoxed is int b)
{
Console.WriteLine(a + b); // output: 30
}
Чтобы проверить только тип выражения, используйте отмену _ вместо имени переменной, как показано в следующем примере:
public abstract class Vehicle {}
public class Car : Vehicle {}
public class Truck : Vehicle {}
public static class TollCalculator
{
public static decimal CalculateToll(this Vehicle vehicle) => vehicle switch
{
Car _ => 2.00m,
Truck _ => 7.50m,
null => throw new ArgumentNullException(nameof(vehicle)),
_ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
};
}
Для этого используйте шаблон типа, как показано в следующем примере:
public static decimal CalculateToll(this Vehicle vehicle) => vehicle switch
{
Car => 2.00m,
Truck => 7.50m,
null => throw new ArgumentNullException(nameof(vehicle)),
_ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
};
Как и шаблон объявления, шаблон типа соответствует выражению, если результат выражения не имеет значения NULL, а его тип времени выполнения удовлетворяет любым из предыдущих условий.
Чтобы проверить наличие ненулевого значения, используйте незначимыйnullшаблон константы, как показано в следующем примере:
if (input is not null)
{
// ...
}
Дополнительные сведения см. в разделах Шаблон объявления и Шаблон типа в примечаниях к предлагаемой функции.
Шаблон константы
Шаблон константы является альтернативным синтаксисом, если == правый операнд является константой. Используйте шаблон константы , чтобы проверить, равен ли результат выражения заданной константы, как показано в следующем примере:
public static decimal GetGroupTicketPrice(int visitorCount) => visitorCount switch
{
1 => 12.0m,
2 => 20.0m,
3 => 27.0m,
4 => 32.0m,
0 => 0.0m,
_ => throw new ArgumentException($"Not supported number of visitors: {visitorCount}", nameof(visitorCount)),
};
В шаблоне константы можно использовать любое константное выражение, например:
- целочисленный литерал или литерал с плавающей точкой;
- char
- строковый литерал
- логическое значение
trueилиfalse; - значение типа enum;
- имя объявленного поля с модификатором const или локального элемента.
null
Выражение должно быть типом, который преобразуется в тип константы, за исключением выражения, тип которого совпадает Span<char>ReadOnlySpan<char> с константными строками.
Используйте шаблон константы для проверки на null, как показано в следующем примере:
if (input is null)
{
return;
}
Компилятор гарантирует, что при вычислении выражения == не будет вызван перегруженный пользователем оператор равенства x is null.
Для проверки наличия непустой константы можно использовать ненулевой null шаблон, как показано в следующем примере:
if (input is not null)
{
// ...
}
Дополнительные сведения см. в разделе Шаблон константы в примечании к предлагаемой функции.
Реляционные шаблоны
Используйте реляционный шаблон для сравнения результата выражения с константой, как показано в следующем примере:
Console.WriteLine(Classify(13)); // output: Too high
Console.WriteLine(Classify(double.NaN)); // output: Unknown
Console.WriteLine(Classify(2.4)); // output: Acceptable
static string Classify(double measurement) => measurement switch
{
< -4.0 => "Too low",
> 10.0 => "Too high",
double.NaN => "Unknown",
_ => "Acceptable",
};
В реляционном шаблоне можно использовать любые операторы отношений — <, >, <=, >=. Правая часть реляционного шаблона должна быть константным выражением. Константное выражение может быть целым числом, числом с плавающей точкой, символом или иметь тип enum.
Чтобы проверить, находится ли результат выражения в определенном диапазоне, сопоставьте его с and (), как показано в следующем примере:
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 3, 14))); // output: spring
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 7, 19))); // output: summer
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 2, 17))); // output: winter
static string GetCalendarSeason(DateTime date) => date.Month switch
{
>= 3 and < 6 => "spring",
>= 6 and < 9 => "summer",
>= 9 and < 12 => "autumn",
12 or (>= 1 and < 3) => "winter",
_ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
Если результат выражения — null или его не удается преобразовать в тип константы с помощью преобразования, допускающего значение NULL, или распаковки-преобразования, то реляционный шаблон не соответствует выражению.
Дополнительные сведения см. в разделе Реляционные шаблоны в примечании к предлагаемой функции.
Логические шаблоны
notИспользуйте комбинаторы шаблонов andи or шаблонов для создания следующих логических шаблонов:
Шаблон отрицания
not, который соответствует выражению, если шаблон с отрицанием не соответствует выражению. В следующем примере показано, как можно инвертировать шаблон константыnull, чтобы проверить, имеет ли выражение значение, отличное от NULL:if (input is not null) { // ... }Шаблон конъюнкции
and, который соответствует выражению, если оба шаблона соответствуют этому выражению. В следующем примере показано, как можно объединить реляционные шаблоны, чтобы проверить, находится ли значение в определенном диапазоне:Console.WriteLine(Classify(13)); // output: High Console.WriteLine(Classify(-100)); // output: Too low Console.WriteLine(Classify(5.7)); // output: Acceptable static string Classify(double measurement) => measurement switch { < -40.0 => "Too low", >= -40.0 and < 0 => "Low", >= 0 and < 10.0 => "Acceptable", >= 10.0 and < 20.0 => "High", >= 20.0 => "Too high", double.NaN => "Unknown", };Отсоставленный
orшаблон, соответствующий выражению, когда любой шаблон соответствует выражению, как показано в следующем примере:Console.WriteLine(GetCalendarSeason(new DateTime(2021, 1, 19))); // output: winter Console.WriteLine(GetCalendarSeason(new DateTime(2021, 10, 9))); // output: autumn Console.WriteLine(GetCalendarSeason(new DateTime(2021, 5, 11))); // output: spring static string GetCalendarSeason(DateTime date) => date.Month switch { 3 or 4 or 5 => "spring", 6 or 7 or 8 => "summer", 9 or 10 or 11 => "autumn", 12 or 1 or 2 => "winter", _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."), };
Как показано в предыдущем примере, блоки объединения в шаблоне можно использовать многократно.
Приоритет и порядок проверки
Комбинаторы шаблонов следуют этому порядку на основе порядка привязки выражений:
notandor
Шаблон not сначала привязывается к операнду. Шаблон and привязывается после любой not привязки выражения шаблона. Шаблон or привязывается после всех not и and шаблонов привязывается к операндам. В следующем примере показано, как сопоставить все символы, которые не являются строчными буквами. a - z Она имеет ошибку, так как not шаблон привязывается к шаблону and :
// Incorrect pattern. `not` binds before `and`
static bool IsNotLowerCaseLetter(char c) => c is not >= 'a' and <= 'z';
Привязка по умолчанию означает, что предыдущий пример анализируется в следующем примере:
// The default binding without parentheses is shows in this method. `not` binds before `and`
static bool IsNotLowerCaseLetterDefaultBinding(char c) => c is ((not >= 'a') and <= 'z');
Чтобы устранить ошибку not , укажите, что шаблон привязывается к выражению >= 'a' and <= 'z' :
// Correct pattern. Force `and` before `not`
static bool IsNotLowerCaseLetterParentheses(char c) => c is not (>= 'a' and <= 'z');
Добавление круглых скобок становится более важным, так как шаблоны становятся более сложными. Как правило, используйте скобки для уточнения шаблонов для других разработчиков, как показано в следующем примере:
static bool IsLetter(char c) => c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z');
Примечание.
Порядок проверки шаблонов с одинаковым порядком привязки не определен. Во время выполнения можно сначала проверить вложенные справа шаблоны нескольких or шаблонов и нескольких and шаблонов.
Дополнительные сведения см. в разделе Блоки объединения шаблонов в примечании к предлагаемой функции.
Шаблон свойства
Используйте шаблон свойства для сопоставления свойств или полей выражения с вложенными шаблонами, как показано в следующем примере:
static bool IsConferenceDay(DateTime date) => date is { Year: 2020, Month: 5, Day: 19 or 20 or 21 };
Шаблон свойства соответствует выражению, если результат выражения не равен null, и каждый вложенный шаблон соответствует соответствующему свойству или полю результата выражения.
Вы можете добавить проверку типа выполнения и объявление переменной в шаблон свойств, как показано в следующем примере:
Console.WriteLine(TakeFive("Hello, world!")); // output: Hello
Console.WriteLine(TakeFive("Hi!")); // output: Hi!
Console.WriteLine(TakeFive(new[] { '1', '2', '3', '4', '5', '6', '7' })); // output: 12345
Console.WriteLine(TakeFive(new[] { 'a', 'b', 'c' })); // output: abc
static string TakeFive(object input) => input switch
{
string { Length: >= 5 } s => s.Substring(0, 5),
string s => s,
ICollection<char> { Count: >= 5 } symbols => new string(symbols.Take(5).ToArray()),
ICollection<char> symbols => new string(symbols.ToArray()),
null => throw new ArgumentNullException(nameof(input)),
_ => throw new ArgumentException("Not supported input type."),
};
Эта конструкция специально означает, что шаблон is { }пустого свойства соответствует всему ненулевому значению, и его можно использовать вместо is not null создания переменной: somethingPossiblyNull is { } somethingDefinitelyNotNull
if (GetSomeNullableStringValue() is { } nonNullValue) // Empty property pattern with variable creation
{
Console.WriteLine("NotNull:" + nonNullValue);
}
else
{
nonNullValue = "NullFallback"; // we can access the variable here.
Console.WriteLine("it was null, here's the fallback: " + nonNullValue);
}
Шаблон свойства является рекурсивным шаблоном. Вы можете использовать любой шаблон как вложенный шаблон. Используйте шаблон свойства для сопоставления элементов данных с вложенными шаблонами, как показано в следующем примере:
public record Point(int X, int Y);
public record Segment(Point Start, Point End);
static bool IsAnyEndOnXAxis(Segment segment) =>
segment is { Start: { Y: 0 } } or { End: { Y: 0 } };
В предыдущем примере используется orкомбинатор шаблонов и типы записей.
В шаблоне свойств можно ссылаться на вложенные свойства или поля. Эта возможность называется шаблоном расширенных свойств. Например, можно выполнить рефакторинг метода из предыдущего примера в следующий эквивалентный код:
static bool IsAnyEndOnXAxis(Segment segment) =>
segment is { Start.Y: 0 } or { End.Y: 0 };
Дополнительные сведения см. в разделе Шаблон свойства в примечании к предлагаемой функции и примечание к предлагаемой функции Расширенные шаблоны свойств.
Совет
Чтобы улучшить удобочитаемость кода, используйте правило стиля "Упрощение свойств" (IDE0170). Он предлагает места для использования шаблонов расширенных свойств.
Позиционный шаблон
Используйте позиционный шаблон для деконструкции выражения и сопоставления результирующего значения с соответствующими вложенными шаблонами, как показано в следующем примере:
public readonly struct Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y) => (X, Y) = (x, y);
public void Deconstruct(out int x, out int y) => (x, y) = (X, Y);
}
static string Classify(Point point) => point switch
{
(0, 0) => "Origin",
(1, 0) => "positive X basis end",
(0, 1) => "positive Y basis end",
_ => "Just a point",
};
В предыдущем примере тип выражения содержит метод деконструкции , который используется шаблоном для деконструкции результата выражения.
Внимание
Порядок элементов в позициальном шаблоне должен соответствовать порядку параметров в методе Deconstruct . Код, созданный для позиционного шаблона, вызывает Deconstruct метод.
Можно также сопоставлять выражения кортежных типов с позиционными шаблонами. С помощью этого подхода можно сопоставить несколько входных данных с различными шаблонами, как показано в следующем примере:
static decimal GetGroupTicketPriceDiscount(int groupSize, DateTime visitDate)
=> (groupSize, visitDate.DayOfWeek) switch
{
(<= 0, _) => throw new ArgumentException("Group size must be positive."),
(_, DayOfWeek.Saturday or DayOfWeek.Sunday) => 0.0m,
(>= 5 and < 10, DayOfWeek.Monday) => 20.0m,
(>= 10, DayOfWeek.Monday) => 30.0m,
(>= 5 and < 10, _) => 12.0m,
(>= 10, _) => 15.0m,
_ => 0.0m,
};
В предыдущем примере используются реляционные и логические шаблоны.
В позиционном шаблоне можно использовать имена элементов кортежа и параметры метода Deconstruct, как показано в следующем примере:
var numbers = new List<int> { 1, 2, 3 };
if (SumAndCount(numbers) is (Sum: var sum, Count: > 0))
{
Console.WriteLine($"Sum of [{string.Join(" ", numbers)}] is {sum}"); // output: Sum of [1 2 3] is 6
}
static (double Sum, int Count) SumAndCount(IEnumerable<int> numbers)
{
int sum = 0;
int count = 0;
foreach (int number in numbers)
{
sum += number;
count++;
}
return (sum, count);
}
Можно также расширить позиционный шаблон одним из следующих способов:
Добавьте проверку типа среды выполнения и объявление переменной, как показано в следующем примере:
public record Point2D(int X, int Y); public record Point3D(int X, int Y, int Z); static string PrintIfAllCoordinatesArePositive(object point) => point switch { Point2D (> 0, > 0) p => p.ToString(), Point3D (> 0, > 0, > 0) p => p.ToString(), _ => string.Empty, };В предыдущем примере используются позиционные записи, которые неявно обеспечивают выполнение метода
Deconstruct.Используйте шаблон свойства в позиционном шаблоне, как показано в следующем примере:
public record WeightedPoint(int X, int Y) { public double Weight { get; set; } } static bool IsInDomain(WeightedPoint point) => point is (>= 0, >= 0) { Weight: >= 0.0 };Можно объединить два предыдущих варианта, как показано в следующем примере:
if (input is WeightedPoint (> 0, > 0) { Weight: > 0.0 } p) { // .. }
Позиционный шаблон является рекурсивным шаблоном. Это значит, что любой шаблон можно использовать как вложенный шаблон.
Дополнительные сведения см. в разделе Позиционный шаблон в примечании к предлагаемой функции.
Шаблон var
var
Используйте шаблон для сопоставления любого выражения, в том числе nullи назначения результата новой локальной переменной, как показано в следующем примере:
static bool IsAcceptable(int id, int absLimit) =>
SimulateDataFetch(id) is var results
&& results.Min() >= -absLimit
&& results.Max() <= absLimit;
static int[] SimulateDataFetch(int id)
{
var rand = new Random();
return Enumerable
.Range(start: 0, count: 5)
.Select(s => rand.Next(minValue: -10, maxValue: 11))
.ToArray();
}
Шаблон var полезно использовать, если в логическом выражении вам требуется временная переменная для хранения результатов промежуточных вычислений. Вы также можете использовать var шаблон, если необходимо выполнить дополнительные проверки в when случае защиты switch выражения или инструкции, как показано в следующем примере:
public record Point(int X, int Y);
static Point Transform(Point point) => point switch
{
var (x, y) when x < y => new Point(-x, y),
var (x, y) when x > y => new Point(x, -y),
var (x, y) => new Point(x, y),
};
static void TestTransform()
{
Console.WriteLine(Transform(new Point(1, 2))); // output: Point { X = -1, Y = 2 }
Console.WriteLine(Transform(new Point(5, 2))); // output: Point { X = 5, Y = -2 }
}
В предыдущем примере шаблон var (x, y) эквивалентен позиционному шаблону (var x, var y).
В шаблоне var тип объявленной переменной — это тип времени компиляции выражения, соответствующего шаблону.
Дополнительные сведения см. в разделе Шаблон var в примечании к предлагаемой функции.
Шаблон пустой переменной
Используйте шаблон_ отмены для сопоставления любого выражения, в том числе null, как показано в следующем примере:
Console.WriteLine(GetDiscountInPercent(DayOfWeek.Friday)); // output: 5.0
Console.WriteLine(GetDiscountInPercent(null)); // output: 0.0
Console.WriteLine(GetDiscountInPercent((DayOfWeek)10)); // output: 0.0
static decimal GetDiscountInPercent(DayOfWeek? dayOfWeek) => dayOfWeek switch
{
DayOfWeek.Monday => 0.5m,
DayOfWeek.Tuesday => 12.5m,
DayOfWeek.Wednesday => 7.5m,
DayOfWeek.Thursday => 12.5m,
DayOfWeek.Friday => 5.0m,
DayOfWeek.Saturday => 2.5m,
DayOfWeek.Sunday => 2.0m,
_ => 0.0m,
};
В предыдущем примере дескриптор шаблона отмены null и любое целочисленное значение, которое не имеет соответствующего DayOfWeek члена перечисления. Это гарантирует, что switch выражение в примере обрабатывает все возможные входные значения. Если в выражении switch не используется шаблон пустой переменной и при этом ни один из шаблонов выражения не соответствует входным данным, среда выполнения генерирует исключение. Если выражение switch не обрабатывает все возможные входные значения, компилятор генерирует предупреждение.
Шаблон отмены не может быть шаблоном is в выражении или операторе switch . В этих случаях для сопоставления выражений используйте var с пустой переменной: var _. Шаблон отмены может быть шаблоном switch в выражении.
Дополнительные сведения см. в разделе Шаблон пустой переменной в примечании к предлагаемой функции.
Шаблон в круглых скобках
Круглые скобки можно поместить вокруг любого шаблона. Как правило, это делается для того, чтобы подчеркнуть или изменить приоритет логических шаблонов, как показано в следующем примере:
if (input is not (float or double))
{
return;
}
Шаблоны списков
Вы можете сопоставить массив или список с последовательностью шаблонов, как показано в следующем примере:
int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers is [1, 2, 3]); // True
Console.WriteLine(numbers is [1, 2, 4]); // False
Console.WriteLine(numbers is [1, 2, 3, 4]); // False
Console.WriteLine(numbers is [0 or 1, <= 2, >= 3]); // True
Как показано в предыдущем примере, шаблон списка совпадает, когда каждый вложенный шаблон соответствует соответствующему элементу входной последовательности. Вы можете использовать любой шаблон в шаблоне списка. Чтобы сопоставить любой элемент, используйте шаблон отмены или, если вы также хотите записать элемент, используйте шаблон var, как показано в следующем примере:
List<int> numbers = new() { 1, 2, 3 };
if (numbers is [var first, _, _])
{
Console.WriteLine($"The first element of a three-item list is {first}.");
}
// Output:
// The first element of a three-item list is 1.
Приведенные выше примеры соответствуют всей входной последовательности по шаблону списка. Чтобы сопоставить элементы только в начале или в конце входной последовательности, используйте шаблон..среза, как показано в следующем примере:
Console.WriteLine(new[] { 1, 2, 3, 4, 5 } is [> 0, > 0, ..]); // True
Console.WriteLine(new[] { 1, 1 } is [_, _, ..]); // True
Console.WriteLine(new[] { 0, 1, 2, 3, 4 } is [> 0, > 0, ..]); // False
Console.WriteLine(new[] { 1 } is [1, 2, ..]); // False
Console.WriteLine(new[] { 1, 2, 3, 4 } is [.., > 0, > 0]); // True
Console.WriteLine(new[] { 2, 4 } is [.., > 0, 2, 4]); // False
Console.WriteLine(new[] { 2, 4 } is [.., 2, 4]); // True
Console.WriteLine(new[] { 1, 2, 3, 4 } is [>= 0, .., 2 or 4]); // True
Console.WriteLine(new[] { 1, 0, 0, 1 } is [1, 0, .., 0, 1]); // True
Console.WriteLine(new[] { 1, 0, 1 } is [1, 0, .., 0, 1]); // False
Шаблон среза соответствует нулю или нескольким элементам. В шаблоне списка можно использовать по крайней мере один шаблон среза. Шаблон среза может отображаться только в шаблоне списка.
Вы также можете вложить подпаттерн в шаблон среза, как показано в следующем примере:
void MatchMessage(string message)
{
var result = message is ['a' or 'A', .. var s, 'a' or 'A']
? $"Message {message} matches; inner part is {s}."
: $"Message {message} doesn't match.";
Console.WriteLine(result);
}
MatchMessage("aBBA"); // output: Message aBBA matches; inner part is BB.
MatchMessage("apron"); // output: Message apron doesn't match.
void Validate(int[] numbers)
{
var result = numbers is [< 0, .. { Length: 2 or 4 }, > 0] ? "valid" : "not valid";
Console.WriteLine(result);
}
Validate(new[] { -1, 0, 1 }); // output: not valid
Validate(new[] { -1, 0, 0, 1 }); // output: valid
Дополнительные сведения см. в заметке о предложении о функциях шаблонов списка.
Спецификация языка C#
Дополнительные сведения см. в разделе "Шаблоны и сопоставление шаблонов" спецификации языка C#.
Сведения о функциях, добавленных в C# 9 и более поздних версиях, см. в следующих заметках о предложении функций:
- Обновления сопоставления шаблонов
- расширенные шаблоны свойств
- Шаблоны списка
-
Сопоставление
Span<char>шаблонов в строковом литерале