Span and Memory · TL;DR
1 min readTL;DR
Span<T> is a view over a contiguous block of memory: a reference to the first element plus a length, 16 bytes on 64-bit, that can point into a managed array, a string (ReadOnlySpan<char>), memory on the stack (stackalloc) or native memory, with the same type-safe, bounds-checked API for all of them. Slicing a span creates another view over the same memory, so parsing and processing text or binary data needs no copies and no allocations ("2024-06-01".AsSpan(0, 4) instead of Substring). Because a span may point to the stack, it is a ref struct: it can only live on the stack, so it cannot be a field of a class, be boxed, be captured by a lambda, or survive an await or yield. When you need to store a buffer on the heap or use it across await, use Memory<T> / ReadOnlyMemory<T> and call .Span at the point of use. Typical wins: allocation-free parsing, formatting, protocol and file handling, and replacing Substring, Split and temporary arrays on hot paths.