День семьдесят второй. #CSharp8
Новые функции в C# 8.
3. Продвинутое Сопоставление с Шаблоном
Сопоставление выражения с шаблоном предоставляет инструменты для сравнения по форме связанных, но разных типов данных. В C# 7.0 был представлен синтаксис шаблонов типа и шаблонов констант, используя выражения
C# 8.0 расширяет эту функциональность, так что вы можете использовать больше шаблонных выражений в разнообразных местах вашего кода. Используйте эти функции, когда ваши данные и функционал разделены, когда ваши алгоритмы не зависят от типа объекта во время выполнения. В дополнение к новым шаблонам в новых местах, в C# 8.0 вводятся рекурсивные шаблоны. Результат любого шаблона выражения – это выражение. Рекурсивный шаблон – это просто шаблон выражения, применённый к результату другого шаблона выражения.
Преимущества
Рекурсивное сопоставление с шаблоном помогает вам разбить структуры данных на компоненты и использовать их в очень удобном и компактном синтаксисе. Несмотря на то, что сопоставление с шаблоном эквивалентно последовательности выражений if-then, оно помогает вам писать код в стиле функционального программирования.
Недостатки
В сложных выражениях синтаксис может быть хитрым и сложным для понимания.
В следующем примере шаблон выражения используется для сопоставления структуры с шаблоном:
Шаблон свойства позволяет вам сопоставить свойства исследуемого объекта. В следующем примере метод рассчитывает налог с продаж в зависимости от штата (свойство
Некоторые типы включают метод
Источники:
- https://www.c-sharpcorner.com/article/c-sharp-8-features/
- https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8
Новые функции в C# 8.
3. Продвинутое Сопоставление с Шаблоном
Сопоставление выражения с шаблоном предоставляет инструменты для сравнения по форме связанных, но разных типов данных. В C# 7.0 был представлен синтаксис шаблонов типа и шаблонов констант, используя выражения
is
и switch
. C# 8.0 расширяет эту функциональность, так что вы можете использовать больше шаблонных выражений в разнообразных местах вашего кода. Используйте эти функции, когда ваши данные и функционал разделены, когда ваши алгоритмы не зависят от типа объекта во время выполнения. В дополнение к новым шаблонам в новых местах, в C# 8.0 вводятся рекурсивные шаблоны. Результат любого шаблона выражения – это выражение. Рекурсивный шаблон – это просто шаблон выражения, применённый к результату другого шаблона выражения.
Преимущества
Рекурсивное сопоставление с шаблоном помогает вам разбить структуры данных на компоненты и использовать их в очень удобном и компактном синтаксисе. Несмотря на то, что сопоставление с шаблоном эквивалентно последовательности выражений if-then, оно помогает вам писать код в стиле функционального программирования.
Недостатки
В сложных выражениях синтаксис может быть хитрым и сложным для понимания.
В следующем примере шаблон выражения используется для сопоставления структуры с шаблоном:
var point = new 3DPoint(1, 2, 3); //x=1, y=2, z=3Шаблоны свойств
if (point is 3DPoint(1, var myY, _))
{
// Этот код будет выполнен, только если point.X == 1
// myY – это новая переменная,
// которая будет доступна только в этом блоке
// Третий член объекта игнорируется спецсимволом _
}
Шаблон свойства позволяет вам сопоставить свойства исследуемого объекта. В следующем примере метод рассчитывает налог с продаж в зависимости от штата (свойство
State
извлекается из передаваемого объекта типа Address
). Расчёт этого налога не является ответственностью класса Address
, поскольку он может изменяться гораздо чаще, чем структура адреса:public static decimal ComputeSalesTax(Address location, decimal salePrice) =>Позиционные шаблоны
location switch
{
{ State: "WA" } => salePrice * 0.06M,
{ State: "MN" } => salePrice * 0.075M,
{ State: "MI" } => salePrice * 0.05M,
// ...
_ => 0M
};
Некоторые типы включают метод
Deconstruct
, который деконструирует свойства в отдельные переменные. Когда доступен метод Deconstruct
, вы можете использовать позиционные шаблоны для сопоставления свойств с шаблоном. Рассмотрим следующий класс точки с координатами X
и Y
:public class 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);
}
public enum QuadrantСледующий метод использует позиционный шаблон для извлечения значений
{
Unknown,
Origin,
One,
Two,
Three,
Four,
OnBorder
}
x
и y
, а также использует условие when
для определения квадранта:static Quadrant GetQuadrant(Point point) => point switchШаблон пустого кортежа
{
(0, 0) => Quadrant.Origin,
var (x, y) when x > 0 && y > 0 => Quadrant.One,
var (x, y) when x < 0 && y > 0 => Quadrant.Two,
var (x, y) when x < 0 && y < 0 => Quadrant.Three,
var (x, y) when x > 0 && y < 0 => Quadrant.Four,
var (_, _) => Quadrant.OnBorder,
_ => Quadrant.Unknown
};
(_, _)
соответствует случаю, когда либо x
, либо y
равно 0, но не оба. Выражение switch
должно либо возвращать значение, либо выбрасывать исключение. Если ни один из вариантов не находит соответствия, выражение switch
выбрасывает исключение. Компилятор выдаст предупреждение, если вы не укажете все возможные варианты в выражении switch
.Источники:
- https://www.c-sharpcorner.com/article/c-sharp-8-features/
- https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8