Язык 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 } => "Грузовик легкого класса",
_ => "Неизвестное транспортное средство"
};
Использование расширенных шаблонов свойств
Способность сопоставлять вложенные свойства с расширенными шаблонами свойств может упростить ваш код, сделав его более читаемым и поддерживаемым. Вот несколько советов по максимизации преимуществ расширенных шаблонов свойств в ваших проектах:
Рефакторинг сложных условных конструкций: Если у вас есть вложенные операторы if-else или выражения switch, связанные с несколькими свойствами, рассмотрите возможность их рефакторинга с использованием расширенных шаблонов свойств для более краткого и читаемого синтаксиса.
Сочетание с другими возможностями сопоставления с образцом: В C# 10.0 были введены и другие улучшения, такие как шаблоны "and", "or" и "not". Сочетание этих функций с расширенными шаблонами свойств может привести к еще более мощному и выразительному сопоставлению с образцом.
Использование с LINQ и другими API запросов: При фильтрации или проекции данных с использованием LINQ или других API запросов, расширенные шаблоны свойств могут упростить ваш код и сделать его более выразительным.
Применение в существующих кодовых базах: Даже если вы работаете с существующей кодовой базой, вы можете постепенно внедрять расширенные шаблоны свойств для улучшения читаемости и поддерживаемости кода со временем.
Заключение
Расширенные шаблоны свойств предоставляют разработчикам мощный инструмент для упрощения сложных условий switch-ей и повышения читаемости кода. Понимая полный потенциал этой функции и эффективно применяя ее в своих проектах, вы сможете создать более выразительный, краткий и поддерживаемый код.
Можно ли работать и не знать паттернов - да. Можно ли с ними не столкнуться - нет. Приглашаю вас на бесплатный урок, где обсудим паттерны проектирования в C#: абстрактная фабрика, декоратор и другие.