TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #2379 2.74K
День 1968. #ЗаметкиНаПолях
Различия Между Span и Memory в C#

Сегодня разберём особенности типов Span и Memory в .NET, и когда что использовать.

Span<T>
Это ref-структура в .NET, представляющая собой доступ к непрерывной области памяти. Т.е. Span<T> — это всего лишь представление блока памяти, а не способ выделить память.
Span<T> может иметь несколько источников блока памяти:
- массив T[] (или его фрагмент)
- Memory<T>
- неуправляемый указатель
- результат stackalloc

Например:
int[] data = [1, 2, 3, 4, 5, 6];
var span = data.AsSpan().Slice(2, 1);

Span<T> всегда располагается в стеке и хранит только указатель на уже выделенный ссылочный тип и не выделяет новую управляемую память в куче. Span<T> нельзя упаковать или назначить переменным типа Object, Dynamic или интерфейсам. Он также не может быть полем ссылочного типа.

Использование Span<T> не требует вычисления начала указателя на ссылочный тип и смещения, поскольку эта информация уже содержится в Span<T>. Это делает вычисления с ним очень быстрыми. Более того, поскольку Span<T> не выделяет дополнительную память в куче, сборщик мусора работает быстрее, что повышает производительность всего приложения.

Memory<T>
Как и Span<T> представляет собой доступ к непрерывной области памяти, однако является структурой. Memory<T> можно разместить как в управляемой куче, так и в стеке, использовать в качестве поля в классе, а также совместно с await и yield.

Свойство Span возвращает Span<T>, что позволяет использовать Memory<T> как Span<T> в рамках одного метода. В этом смысле Memory<T> иногда называют фабрикой Span’ов.

Рекомендации
- Как правило, следует использовать Span<T> в качестве параметра для синхронного API, когда это возможно.
- Если буфер памяти должен быть доступен только для чтения, можно использовать ReadOnlySpan<T> и ReadOnlyMemory<T>.
- Если метод имеет параметр Memory<T> и возвращает void, не следует использовать этот экземпляр Memory<T> после завершения выполнения метода. Аналогично, если метод возвращает Task, не следует использовать экземпляр после завершения задачи.

Итого
Оба типа значительно повышают производительность приложений и обеспечивают безопасность памяти при работе с неуправляемыми ресурсами, важно понимать их последствия и ограничения.

Span<T> и Memory<T> - это представления блока памяти, которые предназначены для предотвращения копирования памяти или выделения большего количества памяти, чем необходимо, для управляемой кучи.

Для быстрых локальных вычислений и во избежание выделения ненужной памяти лучшим выбором является Span. Но, когда нужно передать его в качестве аргумента или использовать в асинхронном методе, приходится использовать Memory, который не имеет ограничений Span’а.

Источник: https://code-maze.com/csharp-differences-between-span-and-memory/
  • 👍 26
More from @netdeveloperdiary
  1. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  2. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
  3. Oct 5, 2026День 2805. #ЧтоНовенького #NET11 Аргументы в Выражениях Коллекций в C#15 В C#15 реализован…
  4. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  5. Oct 3, 2026Post #3360
  6. Oct 3, 2026День 2803. #Оффтоп Чем Заняться, Пока Работают Агенты? У VS Code Есть Ответ Сейчас большую…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →