Как стать автором
Обновить
582.47
OTUS
Цифровые навыки от ведущих экспертов

Record structs в C#: эффективные и безопасные типы данных

Время на прочтение3 мин
Количество просмотров16K

C# 9 представил новую функцию, называемую Запись (record), которая обеспечивает неизменяемость и семантику сравнения на основе значений для классов. Записи упрощают создание типов данных и обеспечивают лучшую безопасность при работе с ними. Однако до C# 10 они были доступны только для классов, теперь же у нас есть record struct, позволяющие применить те же преимущества Записей и к структурам.

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

Рекорды в C#: краткий пересказ

Прежде чем углубляться в record struct, давайте быстро вспомним, что такое Записи и почему они были введены в C#.

Записи — это специальный тип классов, которые предоставляют неизменяемость и сравнение на основе значений. Они идеально подходят для моделирования типов данных, таких как дата, время или координаты. Record обеспечивает сокращенный синтаксис для определения подобных типов и автоматически генерирует методы, такие как Equals, GetHashCode и ToString.

Пример использования:

public record Date(int Year, int Month, int Day);

Date date1 = new Date(2023, 3, 31);
Date date2 = new Date(2023, 3, 31);

Console.WriteLine(date1 == date2); // Вывод: True

Также, немаловажным для кого-то будет и переопределение ToString() для вывода всего содержимого - этакий встроенный сериализатор.

public record Date(int Year, int Month, int Day);

Date date = new Date(2023, 3, 31);

Console.WriteLine(date.ToString()); // Вывод: Date { Year = 2023, Month = 3, Day = 31 }

Record structs

Записи структур предоставляют все преимущества записей, такие как неизменяемость и сравнение на основе значений, для структур. Подобные переменные ведут себя так же, как обычные структуры, только с дополнительными возможностями, предоставляемыми записями. Можно сказать, что это такой синтаксический сахар, чтобы быстро добавить сравнение по значениям и иммутабельность. Однако, если быть до конца честными, то полный список преимуществ состоит не из двух, а аж из пяти пунктов.

1. Производительность и оптимизация памяти

Так как record struct является значимым типом, она хранится на стеке, что обеспечивает лучшую производительность и оптимизацию использования памяти по сравнению с record class. Записи структур идеально подходят для определения маленьких и часто используемых типов данных.

public record struct Vector2D(float X, float Y);
public record struct Vector3D(float X, float Y, float Z);
public record struct Color(byte R, byte G, byte B);

2. Сравнение на основе значений

Как и записи для классов, записи для структур предоставляют сравнение на основе значений, что позволяет сравнивать два экземпляра рекордной структуры на равенство, основываясь на их значениях, а не на их ссылках. Это делает их идеальным выбором для определения типов данных, для которых важно сравнение на основе значений, таких как числовые координаты или дата и время.

Point point1 = new Point(10, 20);
Point point2 = new Point(10, 20);

Console.WriteLine(point1 == point2); // Вывод: True

3. Неизменяемость

Применимо к структурам, записи обеспечивают неизменяемость, что означает, что после создания экземпляра его свойства не могут быть изменены. Это предотвращает случайные изменения состояния и обеспечивает большую надежность и безопасность при работе с данными. Неизменяемость также упрощает понимание и отладку кода, так как вы всегда можете быть уверены, что состояние объекта останется неизменным после создания.

Point point = new Point(10, 20);

// Строка №5 вызовет ошибку компиляции, так
// как свойства записи структуры неизменяемы
//point.X = 30;

4. Сокращенный синтаксис

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

public record struct Rectangle(int Width, int Height);

5. Сравнение в switch и деконструкция

Записи для структур также поддерживают возможность сравнения в switch-выражениях и деконструкцию, что позволяет вам легко извлекать значения свойств или использовать сопоставление с образцом для различных сценариев.

Rectangle rect = new Rectangle(100, 200);

// Деконструкция
(int width, int height) = rect;
Console.WriteLine($"Width: {width}, Height: {height}"); // Вывод: Width: 100, Height: 200

// Сопоставление с образцом
string description = rect switch
{
    (0, 0) => "Пустой прямоугольник",
    (var w, var h) when w == h => "Квадрат",
    (var w, var h) => $"Прямоугольник: ширина {w}, высота {h}"
};

Заключение

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


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

Теги:
Хабы:
Всего голосов 10: ↑8 и ↓2+9
Комментарии10

Публикации

Информация

Сайт
otus.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия
Представитель
OTUS