ref structure types (C# reference)
You can use the ref modifier in the declaration of a structure type. Instances of a ref struct type are allocated on the stack and can't escape to the managed heap. To ensure that, the compiler limits the usage of ref struct types as follows:
- A
ref structcan't be the element type of an array. - A
ref structcan't be a declared type of a field of a class or a non-ref struct. - A
ref structcan't implement interfaces. - A
ref structcan't be boxed to System.ValueType or System.Object. - A
ref structcan't be a type argument. - A
ref structvariable can't be captured by a lambda expression or a local function. - A
ref structvariable can't be used in anasyncmethod. However, you can useref structvariables in synchronous methods, for example, in methods that return Task or Task<TResult>. - A
ref structvariable can't be used in iterators.
You can define a disposable ref struct. To do that, ensure that a ref struct fits the disposable pattern. That is, it has an instance Dispose method, which is accessible, parameterless and has a void return type. You can use the using statement or declaration with an instance of a disposable ref struct.
Typically, you define a ref struct type when you need a type that also includes data members of ref struct types:
public ref struct CustomRef
{
public bool IsValid;
public Span<int> Inputs;
public Span<int> Outputs;
}
To declare a ref struct as readonly, combine the readonly and ref modifiers in the type declaration (the readonly modifier must come before the ref modifier):
public readonly ref struct ConversionRequest
{
public ConversionRequest(double rate, ReadOnlySpan<double> values)
{
Rate = rate;
Values = values;
}
public double Rate { get; }
public ReadOnlySpan<double> Values { get; }
}
In .NET, examples of a ref struct are System.Span<T> and System.ReadOnlySpan<T>.
ref fields
Beginning with C# 11, you can declare a ref field in a ref struct, as the following example shows:
public ref struct RefFieldExample
{
private ref int number;
public int GetNumber()
{
if (System.Runtime.CompilerServices.Unsafe.IsNullRef(ref number))
{
throw new InvalidOperationException("The number ref field is not initialized.");
}
return number;
}
}
A ref field may have the null value. Use the Unsafe.IsNullRef<T>(T) method to determine if a ref field is null.
You can apply the readonly modifier to a ref field in the following ways:
readonly ref: You can ref reassign such a field with the= refoperator only inside a constructor or aninitaccessor. You can assign a value with the=operator at any point allowed by the field access modifier.ref readonly: At any point, you cannot assign a value with the=operator to such a field. However, you can ref reassign a field with the= refoperator.readonly ref readonly: You can only ref reassign such a field in a constructor or aninitaccessor. At any point, you cannot assign a value to the field.
The compiler ensures that a reference stored in a ref field doesn't outlive its referent.
The ref fields feature enables a safe implementation of types like System.Span<T>:
public readonly ref struct Span<T>
{
internal readonly ref T _reference;
private readonly int _length;
// Omitted for brevity...
}
The Span<T> type stores a reference through which it accesses the contiguous elements in memory. The use of a reference enables a Span<T> instance to avoid copying the storage it refers to.
C# language specification
For more information, see the following sections of the C# language specification:
For more information about ref fields, see the Low-level struct improvements proposal note.
See also
.NET feedback
The .NET documentation is open source. Provide feedback here.
Feedback
Submit and view feedback for