День 1639. #ЗаметкиНаПолях
Использовать Записи, Классы или Структуры
Классы и структуры были частью C#, начиная с версии 1.0, но совсем недавно были добавлены записи. Сегодня сравним, где что лучше использовать.
Классы
Классы - наиболее универсальная из доступных структур данных, но требует больше ресурсов. Это не значит, что классы — плохой выбор. Высоко оптимизированные классы предлагают широкий спектр функций, что делает их мощным инструментом для написания кода. Вот типичное определение класса:
public class ApiClient : HttpClient
{
private string _myField = "";
public string MyProperty { get; set; }
public ApiClient()
{
BaseAddress = new Uri("http://api.com");
}
public string MyMethod()
=> "hello";
}
Особенности
- Могут наследовать поведение от других классов.
- Выделение памяти для класса происходит в куче, а не в стеке. Обычно это означает больше накладных расходов, чем при использовании типов-значений. - Классы являются изменяемыми, т.е. их данные могут измениться после создания экземпляра.
Структуры
Структуры лучше всего использовать для представления простых данных с небольшим поведением или без него. Вот типичная реализация структуры:
public struct GeoLocation
{
private double _latitude;
private double _longitude;
public GeoLocation(double lat, double lng)
{
_latitude = lat;
_longitude = lng;
}
public override string ToString()
=> $"(lat: {_latitude}, lon:{_longitude})";
}
Особенности
- Хорошая практика – рассматривать структуры как неизменяемые типы.
- Размещаются в стеке, поэтому выделение/освобождение их обычно намного дешевле, чем при использовании ссылочных типов.
- Не могут наследовать от других.
См. подробнее, когда использовать структуру
Записи
Записи — это облегчённые ссылочные типы с семантикой значений. Кроме того, компилятор «из коробки» предлагает некоторые функции, такие как равенство по значению и форматирование при выводе. Вот два способа определения записи:
// обычный
public record ApiData
{
public int Id { get; init; }
}
// с позиционными параметрами
public record ApiData(int Id);
Особенности
- Записи по умолчанию - ссылочные типы.
- Можно определить конструкторы и свойства.
- Можно использовать наследование.
- Используются как небольшие неизменяемые структуры данных.
- в C# 10 появились структуры-записи (record struct), которые являются структурами, поддерживают все свойства записей, кроме наследования.
Запись стоит использовать, когда нужно инкапсулировать данные без сложного поведения (распространённый пример этого сценария — объекты передачи данных — DTO). Если структура данных будет выполнять сложное поведение и будет большим экземпляром, это признаки того, что нужно использовать класс. Кроме того, лучше выбрать класс, если понадобится изменение данных экземпляра после создания.
Источник: https://code-maze.com/csharp-should-we-use-records-classes-or-structs/