
Язык 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#: абстрактная фабрика, декоратор и другие.
