In traditional C#, slicing a string or an array created a brand new copy of that data in memory. For high-performance parsers (like JSON or CSV readers), this literally wasted Gigabytes of RAM. Span<T> allows us to point to a "Window" of existing memory without copying a single byte.
A Span<T> is a **ref struct**—a type-safe, stack-only pointer. It can point to an Array, an unmanaged memory block, or even data on the Stack.
string bigContent = "ID:54321;STATUS:ACTIVE";
// ❌ OLD WAY: Creates a new string "54321" on the heap
string id = bigContent.Substring(3, 5);
// ✅ MODERN WAY: 'idSpan' is just a pointer to the middle of the original string!
// ZERO memory allocation.
ReadOnlySpan<char> idSpan = bigContent.AsSpan(3, 5);
Because Spans are stack-only for performance, they have strict rules. You cannot use them inside an async method, you cannot store them as fields in a class, and they cannot be used in a List<Span>.
If you need "Span-like" behavior but you are working in an async method, you use Memory<T>. It is a heap-based wrapper that can eventually be converted into a Span when it hits a synchronous method.
Q: "How did Span
Architect Answer: "Before Span, the entire .NET runtime was addicted to 'Substrings.' Every time the framework parsed an HTTP header or a JSON key, it created thousands of tiny string objects. This caused massive Garbage Collector (GC) pressure. By rewriting the core libraries (JSON, HTTP, Regex) to use `ReadOnlySpan