Использование структур
Думаю, всем знакомо понятие структуры (значимого типа) в C#, его особенности и отличия от класса. Но зачем использовать такой «урезанный» класс?
1) Структуры улучшают производительность при использовании небольших коллекций значимых типов, которые вы хотите сгруппировать вместе. Например, точка с координатами:
struct PointВАЖНО! Используйте структуру, если все её поля представляют собой значимые типы. Если хотя бы одно поле ссылочное (например, строковое), используйте класс.
{
public int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
2) В C# использование значимых типов вместо ссылочных приведёт к меньшему количеству обращений к куче, что снизит нагрузку на сборщик мусора, уменьшит количество циклов сборки мусора, и, соответственно, улучшит производительность.
3) При создании структуры переменная, которой она присваивается, содержит реальные данные. В отличие от экземпляра класса, который содержит только ссылку на объект в куче. Когда структура присваивается другой переменной, значения копируются. Таким образом, переменные будут содержать две различные копии одинаковых данных.
MSDN советует создавать структуры, вместо классов, если их экземпляры
- малого размера,
- имеют короткий жизненный цикл,
- часто включаются в другие объекты.
Кроме того, желательно, чтобы создаваемая вами структура отвечала следующим требованиям:
1. Логически представляла единичное значение
Структуры должны использоваться для представления единичного значения, поскольку они являются значимыми типами, как число. Не имеет смысла хранить экземпляр объекта для числа 5. Это важно, потому что структуры передаются по значению. То есть, когда вы передаёте структуру в параметр метода, всё содержимое структуры копируется, и все изменения структуры внутри метода не влияют на исходную переменную, если только вы не передаёте её явно по ссылке.
2. Имела размер экземпляра не больше 16 байт
Этот совет относится исключительно к производительности. 16 байт считается идеальным размером, поскольку структуры копируются по значению. Считается, что копирование 16 байт в стеке потока занимает примерно то же время, что и обращение в кучу по ссылке.
Этот совет не должен быть определяющим. Вы никогда не должны принимать проектные решения, основываясь на производительности, не проведя измерений. См. пост об оптимизации выше.
3. Была неизменяема
Этот совет основан на том, что структуры копируются по значению. Структуры выглядят, как классы, и вы не получите никакого предупреждения, если будете изменять структуру в методе, передавая её туда по значению. Это ведёт к ошибкам, которые легко сделать и сложно потом отследить, что усложняет сопровождение кода. Если ваши структуры неизменяемые, эта ошибка будет исключена.
4. Не подвержена частой упаковке
Избегайте методов или приведений типов, ведущих к упаковке ваших структур, поскольку это дорогостоящая операция с точки зрения производительности.
Ошибочные предположения о структурах:
1. Структуры всегда размещаются в стеке потока, а не в куче
Структуры на самом деле могут размещаться в куче. Куча и стек потока на самом деле только детали реализации языка C#. В спецификации языка ничто не гарантирует, где объект будет размещён.
2. Использование структур вместо классов исключительно из соображений производительности – это нано-оптимизация
Использование структур вместо классов ради производительности – не очень хорошая идея. Даже размер вашей структуры не имеет значения. Используйте структуры, когда это обосновано семантикой программы.
Источники:
https://samrueby.com/2016/09/05/when-should-you-use-a-struct-instead-of-a-class/
https://www.c-sharpcorner.com/article/what-is-structure-and-when-to-use-in-c-sharp/