Span<T> and ReadOnlySpan<T>

C# 7.2 NETCore 2.1

Published Updated Author Jeffrey T. Fritz Reading time

Work with contiguous memory efficiently using safe slices that avoid many temporary allocations.

Span<T> and ReadOnlySpan<T> provide high-performance memory views over arrays, stack memory, and strings. They enable efficient slicing and parsing while staying in managed code.

Why it matters

  • Reduces allocation pressure in parsing and transformation code.
  • Enables fast slicing without copying buffers.
  • Improves throughput in hot paths while retaining type safety.

Cautions

Span<T> is a ref struct, so it cannot be stored on the heap, captured by lambdas, or used across await boundaries. Keep span-based logic synchronous and scoped to the current stack frame.

Slice arrays without allocation

Span slices create lightweight views over existing memory instead of new arrays.

Valid since C# 7.2

using System;

int[] values = { 5, 10, 15, 20, 25, 30 };
Span<int> window = values.AsSpan(1, 3);

for (int i = 0; i < window.Length; i++)
{
    window[i] *= 2;
}

Console.WriteLine(string.Join(", ", values)); // 5, 20, 30, 40, 25, 30

Use ReadOnlySpan<char> over strings

ReadOnlySpan<char> lets you process substrings without allocating new string instances.

Valid since C# 7.2

using System;

string csv = "alpha,beta,gamma";
ReadOnlySpan<char> text = csv.AsSpan();
int separatorIndex = text.IndexOf(',');

ReadOnlySpan<char> firstToken = text[..separatorIndex];
ReadOnlySpan<char> remainder = text[(separatorIndex + 1)..];

Console.WriteLine(firstToken.ToString()); // alpha
Console.WriteLine(remainder.ToString());  // beta,gamma

Learn more

Span<T> (Microsoft Learn)

Newer capabilities

  1. More implicit span conversions

    Introduced in C# 14.0

    C# 14 expands implicit conversions among Span<T> and ReadOnlySpan<T> scenarios, reducing ceremony when passing slices into APIs that accept read-only views.