Виды Структур в C#. Окончание
Начало
3. Ref-структура
Также в C# 7.2 Microsoft представили ref-структуру. ref-структуры гарантированно будут жить в стеке и никогда не смогут попасть в кучу. Благодаря этому вы можете реализовать сценарии с низкой аллокацией, в которых не возникает дополнительной нагрузки на сборщика мусора. Компилятор сделает это за вас, он запретит все сценарии, в которых тип значения перемещается в кучу.
Таким образом, ref-структура НЕ может:
- Быть типом элемента массива, полем класса или полем неref-структуры.
Поскольку массивы и классы всегда живут в куче, понятно, что размещать её там в качестве поля запрещено.
- Быть захвачена лямбда-выражением или локальной функцией.
Лямбда-выражение, а также локальные функции находятся за пределами родительской области видимости, и поэтому их необходимо упаковывать.
- Быть использована в асинхронном методе.
Компилятор создаёт конечный автомат для выполнения продолжения (кода после await), которая сама по себе является классом.
- Быть использована в итераторах.
Та же причина, компилятор создаёт конечный автомат, который продляет область действия/время жизни, и поэтому ref-структура окажется в куче.
- Реализовывать интерфейсы (кроме IDisposable).
Использование ref-структур очень ограничено, но всё же они имеют применение. Одним из наиболее ярких примеров является Span<T>.
4. Ref-структура только для чтения
Модификаторы ref и readonly можно объединить. Это будет означать, что структура должна быть неизменяемой и благодаря ключевому слову ref может находиться только в стеке.
5. Структуры-записи
Появились в C# 10. И подобно записям, которые «расширяют» классы, структуры-записи расширяют структуры. Это хороший синтаксический сахар от компилятора, который даёт вам «предопределённые» реализации Equals, ToString() и GetHashcode.
Мы можем легко переопределить нашу структуру Color:
public record struct Color(Все остальные методы компилятор сгенерирует за вас. Важно, что записи автоматически реализуют IEquatable<T>. Полную реализацию можно посмотреть на Sharplab.io.
byte Red, byte Green, byte Blue)
{
public Color ShiftToGrayscale()
{
var avg = (byte)((Red + Green + Blue) / 3);
return new Color (avg, avg, avg);
}
}
6. Структуры-записи только для чтения
Конечно, вы также можете применить ключевое слово readonly к структуре-записи, оно будет делать то же самое, что и «обычная» структура, то есть компилятор будет налагать определённые ограничения для обеспечения неизменяемости.
7. Ref-структура-запись только для чтения
readonly ref record struct не существует))) Так же, как и ref record struct. Причина очень проста: структура записи реализует IEquatable<T>, а ранее мы видели, что ref-структурам не разрешено реализовывать какой-либо интерфейс, кроме IDisposable.
Источник: https://steven-giesel.com/blogPost/2a52cd8d-b3b2-42e4-87e8-d6dc14147ddb