| Async Streams in C# | Code Coverage and Static Analysis in C# | |
📏 Span<T> in C# |
Span<T> is a value type in C# that represents a contiguous block of memory. It provides a safe, low-overhead way to work with sections of memory from various sources without allocating new memory on the heap. This makes it a powerful tool for writing high-performance, low-allocation code.
Think of Span<T> as a "view" or "slice" into a block of memory. The memory it points to can come from:
ReadOnlySpan<char>).stackalloc keyword).Span<T> is allocated on the stack. This eliminates overhead and reduces garbage collection pressure.ref struct that holds a direct reference and a length, indexing a Span<T> is as fast as indexing a raw array.Span<T> from being used in ways that could lead to memory corruption, such as escaping the stack.Slice() method allows you to easily create a new Span<T> that refers to a subset of the original memory, all without any additional memory allocation.int[] numbers = { 10, 20, 30, 40, 50 };
Span<int> slice = numbers.AsSpan(1, 3); // Refers to elements [20, 30, 40]
foreach (var num in slice)
{
Console.WriteLine(num);
}
Span<T> was introduced in C# 7.2 and supported by the .NET Core 2.1 runtime.
A version was also backported for use with older .NET versions via a NuGet package, but the deepest optimizations were included in .NET Core.
Due to its stack-only nature, Span<T> comes with a few limitations:
async methods, iterator blocks, or across await and yield boundaries.
For asynchronous operations or scenarios where the memory needs to live on the heap, use its companion type Memory<T>.
Memory<T> can be stored on the heap and safely passed across async boundaries.
When you need to perform high-performance, synchronous work on it, you can access its Span property.
Memory<int> memory = new int[] { 1, 2, 3, 4, 5 };
Span<int> span = memory.Span;
span[0] = 99;
Console.WriteLine(memory.Span[0]); // Output: 99
Span<T> is a stack-only, memory-safe type introduced in C# 7.2 that provides a view over contiguous memory. It allows slicing and manipulation of arrays, strings, or unmanaged memory without additional allocations.
using System;
class Program {
static void Main() {
int[] numbers = { 1, 2, 3, 4, 5, 6 };
Span<int> span = numbers;
// Slice the span
Span<int> middle = span.Slice(2, 3); // {3, 4, 5}
// Modify the slice
for (int i = 0; i < middle.Length; i++) {
middle[i] *= 10;
}
// Output original array to show changes
foreach (var num in numbers) {
Console.WriteLine(num);
}
}
}
ReadOnlySpan<T> when you don’t need to modify data.stackalloc for temporary buffers on the stack.Span<T> from methods—it's stack-bound.Memory<T> for async or heap-based scenarios.Memory<T> instead.
Span<T> is a powerful tool for efficient memory access in C#. It’s best suited for performance-sensitive, short-lived operations where safety and speed matter. Use it wisely to write faster and cleaner code.
| Async Streams in C# | Code Coverage and Static Analysis in C# | |