Skip to content

ref fields and scoped ref C# 11.0performancenew scenarios

Allow ref fields inside ref struct types and control ref lifetime with scoped.

ref struct types were introduced in C# 7.2 but could not contain ref fields. This meant low-level types like Span<T> had to be implemented with internal runtime magic rather than expressible C#.

C# 11 allows ref fields inside ref struct types and introduces the scoped modifier to control the lifetime of ref values, preventing them from escaping to a wider scope than intended.

Code

C#
ref struct RefArray
{
    ref int first;
    int length;

    public RefArray(ref int first, int length)
    {
        this.first = ref first;
        this.length = length;
    }

    public ref int this[int index] => ref Unsafe.Add(ref first, index);
}

// scoped prevents a ref parameter from escaping the method
void Process(scoped ref int value)
{
    // Cannot assign 'value' to a field or return it
}
C#
ref struct RefArray
{
    // ref fields were not allowed - had to use pointers or internal tricks
    unsafe int* first;
    int length;

    public unsafe RefArray(int* first, int length)
    {
        this.first = first;
        this.length = length;
    }

    public unsafe ref int this[int index] => ref *(first + index);
}

Notes

  • ref fields can only be declared inside ref struct types
  • The scoped modifier can be applied to ref parameters and locals to restrict their lifetime to the current method
  • Span<T> and ReadOnlySpan<T> are now definable in pure C# using this feature
  • The ref of a ref field can be reassigned using = ref

More information