Язык C# постоянно развивается и в одной из последних версий появились расширенные шаблоны свойств, которые расширяют мощь и универсальность конструкции switch. В этой статье мы рассмотрим расширенные шаблоны свойств в C# 10 на практических примерах и замечаниях о том, как эффективно использовать эти расширенные шаблоны в своих проектах.

Понимание шаблонов свойств

Прежде чем углубляться в расширенные шаблоны свойств, необходимо понять концепцию шаблонов свойств. Введенные в C# 8, шаблоны свойств позволяют разработчикам сопоставлять объекты на основе их свойств, делая сопоставление с образцом более выразительным и кратким. Шаблон свойства объединяет тип объекта и набор условий для свойств этого типа.

Например, рассмотрим простой класс, представляющий человека:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Person person = new Person { Name = "Иван", Age = 25 };

Чтобы классифицировать объект человека на основе его возраста, можно использовать шаблон свойства, как показано ниже:

string category = person switch
{
    { Age: < 18 } => "Несовершеннолетний",
    { Age: >= 18 and < 60 } => "Взрослый",
    { Age: >= 60 } => "Пожилой",
    _ => "Неизвестно"
};

Расширенные шаблоны свойств с C# 10

Хотя шаблоны свойств обеспечивают удобный способ сопоставления объектов на основе их свойств, изначально они были ограничены сопоставлением только с прямыми свойствами объекта. C# 10 расширил шаблоны свойств с помощью поддержки вложенных свойств, что позволяет разработчикам более кратко сопоставлять сложные структуры объектов.

Рассмотрим следующую структуру классов, представляющую компанию и ее сотрудников:

public class Company
{
    public string Name { get; set; }
    public List<Employee> Employees { get; set; }
}

public class Employee
{
    public string Name { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public string City { get; set; }
    public string Country { get; set; }
}

Employee employee = new Employee
{
    Name = "Анна",
    Address = new Address { City = "Нью-Йорк", Country = "США" }
};

В C# теперь можно использовать расширенные шаблоны свойств для сопоставления сотрудников на основе свойств их адреса:

string location = employee switch
{
    { Address: { Country: "США" } } => "Внутренний",
    { Address: { Country: "Канада" } } => "Международный",
    _ => "Неизвестно"
};

Фильтрация сотрудников по местоположению и должности

Предположим, у вас есть набор сотрудников

public class Employee
{
    public string Name { get; set; }
    public string Role { get; set; }
    public Address Address { get; set; }
}

List<Employee> employees = GetEmployees();

и вы хотите отфильтровать сотрудников на основе их местоположения и роли в компании. Вы можете использовать расширенные шаблоны свойств для элегантного решения этой задачи:

var domesticManagers = employees.Where(e =>
    e is { Role: "Менеджер", Address: { Country: "США" } });

var internationalDevelopers = employees.Where(e =>
    e is { Role: "Разработчик", Address: { Country: not "США" } });

Сопоставление сложных структур объектов

Рассмотрим иерархию классов, представляющую компанию по прокату транспортных средств с различными типами транспортных средств:

public abstract class Vehicle
{
    public string Make { get; set; }
    public string Model { get; set; }
    public int Year { get; set; }
}

public class Car : Vehicle
{
    public int NumberOfDoors { get; set; }
    public bool IsElectric { get; set; }
}

public class Motorcycle : Vehicle
{
    public bool HasSidecar { get; set; }
}

public class Truck : Vehicle
{
    public int CargoCapacity { get; set; }
}

Вы можете использовать расширенные шаблоны свойств для определения и категоризации транспортных средств на основе их свойств:

Vehicle vehicle = GetVehicle();

string vehicleCategory = vehicle switch
{
    Car { IsElectric: true, Year: < 2020 } => "Ранний электромобиль",
    Car { IsElectric: true, Year: >= 2020 } => "Современный электромобиль",
    Car { IsElectric: false, NumberOfDoors: >= 4 } => "Традиционный седан",
    Car { IsElectric: false, NumberOfDoors: < 4 } => "Традиционное купе",
    Motorcycle { HasSidecar: true } => "Мотоцикл с коляской",
    Truck { CargoCapacity: >= 5000 } => "Грузовик тяжелого класса",
    Truck { CargoCapacity: < 5000 } => "Грузовик легкого класса",
    _ => "Неизвестное транспортное средство"
};

Использование расширенных шаблонов свойств

Способность сопоставлять вложенные свойства с расширенными шаблонами свойств может упростить ваш код, сделав его более читаемым и поддерживаемым. Вот несколько советов по максимизации преимуществ расширенных шаблонов свойств в ваших проектах:

  1. Рефакторинг сложных условных конструкций: Если у вас есть вложенные операторы if-else или выражения switch, связанные с несколькими свойствами, рассмотрите возможность их рефакторинга с использованием расширенных шаблонов свойств для более краткого и читаемого синтаксиса.

  2. Сочетание с другими возможностями сопоставления с образцом: В C# 10.0 были введены и другие улучшения, такие как шаблоны "and", "or" и "not". Сочетание этих функций с расширенными шаблонами свойств может привести к еще более мощному и выразительному сопоставлению с образцом.

  3. Использование с LINQ и другими API запросов: При фильтрации или проекции данных с использованием LINQ или других API запросов, расширенные шаблоны свойств могут упростить ваш код и сделать его более выразительным.

  4. Применение в существующих кодовых базах: Даже если вы работаете с существующей кодовой базой, вы можете постепенно внедрять расширенные шаблоны свойств для улучшения читаемости и поддерживаемости кода со временем.

Заключение

Расширенные шаблоны свойств предоставляют разработчикам мощный инструмент для упрощения сложных условий switch-ей и повышения читаемости кода. Понимая полный потенциал этой функции и эффективно применяя ее в своих проектах, вы сможете создать более выразительный, краткий и поддерживаемый код.


Можно ли работать и не знать паттернов - да. Можно ли с ними не столкнуться - нет. Приглашаю вас на бесплатный урок, где обсудим паттерны проектирования в C#: абстрактная фабрика, декоратор и другие.

Комментарии (0)