Разбираем Сопоставления по Шаблону в C#. Часть 4/5
Части 1, 2, 3
Позиционный шаблон
Использует деконструктор объекта https://t.me/NetDeveloperDiary/61 или позиционный синтаксис записей для сопоставления по позиции, а не по имени свойства:
public class Rectangle : Shape {
public double Height { get; set; }
public double Width { get; set; }
public override double Area => Height * Width;
public void Deconstruct(
out double width,
out double height) {
width = Width;
height = Height;
}
}
public static string Describe(this Shape shape)
=> shape switch {
Circle r => $"Круг радиуса {r}",
Rectangle(var x, var y)
=> $"прямоугольник {x}x{y} ",
_ => "неизвестная фигура"
};Позиционные шаблоны лучше всего работают с записями, где деконструктор генерируется автоматически, а порядок параметров является частью публичного API. Методы Deconstruct, написанные вручную для изменяемых классов, являются источником ошибок (ширина должна быть первой или высота?). Порядок элементов в шаблоне должен соответствовать порядку выходных параметров в методе Deconstruct, поскольку сгенерированный код вызывает этот метод напрямую.
Шаблон кортежа
Проверяет несколько значений одновременно, заключая их в кортеж. Особенно эффективен, когда решение зависит от комбинации входных данных:
public static string FlagColors(
Color c1, Color c2, Color c3) =>
(c1, c2, c3) switch {
(Color.Blue, Color.White, Color.Red) => "Франция",
(Color.Green, Color.White, Color.Red) => "Италия",
(Color.Black, Color.Red, Color.Yellow) => "Германия",
_ => throw new ArgumentException("Неизвестный флаг")
};
Логические шаблоны: и, или, не
Позволяют создавать более простые шаблоны, не заставляя вас повторять имя переменной:
public static bool LetterOrSeparator(this char c) =>
c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z') or '.' or ',';
Относительные шаблоны: <, >, <=, >=
Превращают лестницу if-else в нечто компактное:
public static double GetTaxRate(double income)
=> income switch {
>= 0 and < 1000 => 0,
< 5000 => 10,
_ => 20
};
Ещё более они полезны в сочетании с шаблонами свойств:
if (shape is Circle { Radius: > 1 and <= 10}) …Окончание следует…
Источник: https://blog.ndepend.com/c-pattern-matching-explained/