Skip to content

C# Feature - Span<T>

Span<T> and ReadOnlySpan<T> provide lightweight views over contiguous memory. They are designed for high-performance code that needs slicing and parsing without extra allocations.

This feature was introduced in C# 7.2 (2017).

Without spans, code often copies data just to work with a subset of it, such as calling Substring(), allocating temporary arrays, or materializing buffers unnecessarily. Span<T> allows code to work with a window into existing memory instead.

  • Use it in parsing, serialization, protocol handling, and performance-sensitive text or byte processing.
  • Use it when slicing existing arrays, strings, or buffers repeatedly.
  • Prefer it when allocations show up in profiling and the data is already contiguous in memory.
char[] copy = text.Substring(0, 5).ToCharArray();
ReadOnlySpan<char> slice = text.AsSpan(0, 5);
ReadOnlySpan<char> line = "GET /health HTTP/1.1".AsSpan();
ReadOnlySpan<char> method = line[..3];
Console.WriteLine(method.ToString()); // GET
Span<int> buffer = stackalloc int[4];
buffer[0] = 10;
buffer[1] = 20;
buffer[2] = 30;
buffer[3] = 40;
  • Spans cannot be stored on the heap, which means they cannot be used as normal fields in reference types.
  • They are powerful but not automatically better for ordinary business logic; use them when performance is actually relevant.
  • APIs returning Span<T> or ReadOnlySpan<T> require careful lifetime reasoning.
  • Span<T> arrived with the broader ref struct work in C# 7.2.
  • Later C# versions made spans more ergonomic through related features such as ranges, indexes, and UTF-8 string literals.