Skip to content

The Abstraction: Span & Memory

🛡️ The Abstraction: Span & Memory

In the previous module, we saw how unsafe pointers allow us to manipulate memory directly. However, pointers are dangerous. Span<T> is the modern .NET solution that provides the performance of pointers with the safety of managed code.


🏗️ 1. Span<T>: The Safe Pointer

Span<T> is a ref struct that lives on the stack. It contains a pointer and a length, but the runtime ensures you never step outside the bounds.

🧩 The Upgrade

  • The Mechanic (Pointers): int* p = &myInt; (Fast but dangerous)
  • The Abstraction (Span): Span<int> s = myBuffer.AsSpan(); (Fast and safe)

How it looks in code:

byte[] largeBuffer = new byte[1024];

// Pointing a 'Window' at a slice of memory
Span<byte> slice = largeBuffer.AsSpan().Slice(10, 50);

slice[0] = 42; // This actually modifies largeBuffer[10]!

🏗️ 2. Memory<T>: Span for the Heap

Span<T> cannot be used in async methods or stored in classes because it is a ref struct (it must stay on the stack). For those cases, we use Memory<T>.

FeatureSpan<T>Memory<T>
LocationStack-onlyStack or Heap
Async SupportNoYes
PerformanceMaximumHigh

🏗️ 3. SIMD: Vectorization (NumPy in C#)

When you need to process large arrays of numbers (like in AI or Data Engineering), you don’t use a for loop. You use SIMD (Single Instruction, Multiple Data).

using System.Runtime.Intrinsics;
using System.Numerics;

// Vectorized addition (Adds 8 ints at once on AVX2)
var v1 = new Vector<int>(array1);
var v2 = new Vector<int>(array2);
var result = v1 + v2;

🚀 The Abstraction’s Advantage

  1. Safety: No more AccessViolationException.
  2. Unified API: Works with arrays, strings, and unmanaged memory (stackalloc) using the same syntax.
  3. Zero-Copy: Parsing strings like JSON or XML without allocating new strings for every property.