Выбор ответа Senior GC, IDisposable и производительность обновлено

Почему Span<T> нельзя хранить в поле класса

Вопрос

Почему Span<T> нельзя сделать полем класса или использовать в async-методе через await?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Это ref struct: может указывать на стек, в кучу ему нельзя. Span<T содержит управляемую ссылку, которая может указывать на stackalloc-буфер, а стек живёт только до выхода из метода.

Варианты ответа

  1. Span слишком большой для поля класса и не помещается в объект
  2. Span не поддерживает обобщённые параметры в полях классов
  3. Это ref struct: может указывать на стек, в кучу ему нельзяправильный ответ
  4. Ограничение снято в C# 12: теперь Span можно хранить в полях

Разбор

Span<T> содержит управляемую ссылку, которая может указывать на stackalloc-буфер, а стек живёт только до выхода из метода. Поэтому ref struct нельзя упаковать, положить в поле класса, захватить в лямбду или держать через await (машина состояний живёт в куче). Для хранения есть Memory<T>, из которого Span получают по месту. Размер тут ни при чём (это две машинных величины). В C# 13 ref struct разрешили в async-методах и итераторах, но только там, где он не пересекает await или yield, так что суть ограничения осталась.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.