`ref` and `unsafe` in Async and Iterator Methods — Unlocking `Span<T>` in C# 13
ref and unsafe in Async and Iterator Methods — Unlocking Span in C# 13 Starting in C# 13, the language lifts one of its long-standing restrictions: the inability to use ref struct types, ref variables, or unsafe contexts in iterator (yield) or async methods. This evolution is critical for developers working with performance-sensitive data, particularly through types like: System.Span System.ReadOnlySpan Custom ref struct types Let’s dive deep into what this change allows, what restrictions remain, and how it helps you write better, faster, and safer C# code. Old Limitation: No ref in async or yield Before C# 13, you couldn’t declare or use: ref locals or ref struct variables in async methods ref locals or ref struct variables in iterator methods unsafe code blocks inside iterator methods This made it impossible to use Span, a high-performance, stack-only data structure, in any method that returned a Task, or used yield return. What’s New in C# 13? C# 13 partially lifts these restrictions: ✅ You can declare ref locals and ref struct variables in async methods ✅ You can use unsafe code in iterator methods ⚠️ But you cannot access those ref locals across an await or yield return This strikes a balance between safety and power. The compiler enforces boundaries to ensure memory safety. Example: Using Span in Async Method public async Task ProcessAsync() { ReadOnlySpan span = stackalloc byte[10]; Console.WriteLine(span[0]); await Task.Delay(100); //

ref
and unsafe
in Async and Iterator Methods — Unlocking Span
in C# 13
Starting in C# 13, the language lifts one of its long-standing restrictions: the inability to use ref struct
types, ref
variables, or unsafe
contexts in iterator (yield
) or async methods.
This evolution is critical for developers working with performance-sensitive data, particularly through types like:
System.Span
System.ReadOnlySpan
- Custom
ref struct
types
Let’s dive deep into what this change allows, what restrictions remain, and how it helps you write better, faster, and safer C# code.
Old Limitation: No ref
in async
or yield
Before C# 13, you couldn’t declare or use:
-
ref
locals orref struct
variables inasync
methods -
ref
locals orref struct
variables in iterator methods -
unsafe
code blocks inside iterator methods
This made it impossible to use Span
, a high-performance, stack-only data structure, in any method that returned a Task
, or used yield return
.
What’s New in C# 13?
C# 13 partially lifts these restrictions:
- ✅ You can declare
ref
locals andref struct
variables inasync
methods - ✅ You can use
unsafe
code in iterator methods - ⚠️ But you cannot access those
ref
locals across anawait
oryield return
This strikes a balance between safety and power. The compiler enforces boundaries to ensure memory safety.
Example: Using Span
in Async Method
public async Task ProcessAsync()
{
ReadOnlySpan<byte> span = stackalloc byte[10];
Console.WriteLine(span[0]);
await Task.Delay(100); //