Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое Records в C#?
Records — это новый ссылочный тип данных, представленный в C# 9.0, предназначенный для создания неизменяемых (immutable) объектов, которые по умолчанию имеют семантику сравнения по значению (value-based equality). Они идеально подходят для моделирования данных, где важна неизменяемость и естественное сравнение, например, DTO (Data Transfer Objects), события доменной модели, результаты запросов.
Ключевые особенности Records
-
Неизменяемость по умолчанию
Основное свойство records — их иммутабельность. После создания экземпляра record его состояние нельзя изменить. Это обеспечивает потокобезопасность и предотвращает случайные изменения данных. -
Сравнение по значению
В отличие от классов, которые сравниваются по ссылке, records автоматически реализуют сравнение на основе значений всех свойств. Два экземпляра record считаются равными, если все их свойства содержат одинаковые значения. -
Синтаксис с ключевым словом
record
Records объявляются с использованием ключевого словаrecord. Самый простой способ — позиционные records, где свойства определяются через параметры конструктора.
public record Person(string FirstName, string LastName, int Age);
При таком объявлении автоматически генерируются:
- Публичные свойства
FirstName,LastName,Ageтолько для чтения (init). - Конструктор, принимающий все свойства.
- Переопределённые методы
Equals,GetHashCode,ToString. - Метод
Deconstructдля деконструкции.
Практическое использование
Создание и использование record:
// Создание экземпляра
var person1 = new Person("Иван", "Петров", 30);
// Неизменяемость: следующая строка вызовет ошибку компиляции
// person1.Age = 31;
// Сравнение по значению
var person2 = new Person("Иван", "Петров", 30);
Console.WriteLine(person1 == person2); // True
// Деконструкция
var (firstName, lastName, age) = person1;
Console.WriteLine($"{firstName} {lastName}, {age} лет");
// Клонирование с изменениями (non-destructive mutation)
var person3 = person1 with { Age = 31 };
Console.WriteLine(person3); // Person { FirstName = Иван, LastName = Петров, Age = 31 }
Отличия от классов и структур
| Особенность | Record | Class | Struct |
|---|---|---|---|
| Тип | Ссылочный | Ссылочный | Значимый |
| Неизменяемость | По умолчанию | Нет (требуется ручная реализация) | Может быть изменяемой |
| Равенство | По значению | По ссылке (без переопределения) | По значению |
| Наследование | Поддерживается | Поддерживается | Не поддерживается |
Расширенные возможности
Records с наследованием:
public record Employee(string FirstName, string LastName, int Age, string Department)
: Person(FirstName, LastName, Age);
var employee = new Employee("Анна", "Сидорова", 28, "IT");
Ручная реализация свойств:
public record Product
{
public string Name { get; init; }
public decimal Price { get; init; }
public Product(string name, decimal price)
{
Name = name;
Price = price;
}
}
Когда использовать Records?
✅ Идеальные случаи:
- Моделирование DTO для API-запросов/ответов
- Возвращаемые значения из методов, где важна неизменяемость
- Ключи в словарях (благодаря корректной реализации GetHashCode)
- События и сообщения в системах событийного программирования
❌ Не рекомендуется:
- Для сущностей с изменяемым состоянием (например, Entity Framework Core сущности)
- Когда требуется полный контроль над каждым аспектом поведения объекта
- В высокопроизводительных сценариях, где накладные расходы на сравнение критичны
Под капотом
При компиляции record преобразуется в класс с:
- Автоматически сгенерированными свойствами только для чтения
- Переопределёнными
Equals,GetHashCode,ToString - Реализацией интерфейса
IEquatable<T> - Методом
Cloneдля поддержки выраженияwith
Records представляют собой мощный инструмент в арсенале C#-разработчика, значительно упрощающий работу с неизменяемыми данными и уменьшающий boilerplate-код. Их внедрение соответствует современным трендам функционального программирования и способствует написанию более безопасного и предсказуемого кода.