Skip to content

ref readonly methods returns C# 7.2performancecorrectness

Return references that cannot be modified by the caller.

C# 7.0 introduced ref return, allowing methods to return references to variables for improved performance. However, this also gave callers the ability to modify the returned reference, which wasn't always desirable.

C# 7.2 adds ref readonly returns, which allow methods to return references for efficient read access without allowing the caller to modify the underlying value. This is particularly useful when returning large structs or accessing read-only data.

Code

C#
readonly struct Point
{
    public readonly double X;
    public readonly double Y;

    public Point(double x, double y) => (X, Y) = (x, y);
}

class Polygon
{
    private Point[] _vertices;

    public ref readonly Point GetVertex(int index)
    {
        return ref _vertices[index];
    }
}

// Usage
var polygon = new Polygon();
ref readonly Point vertex = ref polygon.GetVertex(0);
// vertex.X = 10; // Compile error: cannot modify readonly reference
Console.WriteLine(vertex.X); // OK: can read the value
C#
struct Point
{
    public double X;
    public double Y;

    public Point(double x, double y) => (X, Y) = (x, y);
}

class Polygon
{
    private Point[] _vertices;

    public Point GetVertex(int index)
    {
        return _vertices[index]; // Copies the entire struct
    }
}

// Usage
var polygon = new Polygon();
Point vertex = polygon.GetVertex(0); // Full copy of the struct
Console.WriteLine(vertex.X);

Notes

  • Use ref readonly in the return type to indicate the reference cannot be modified
  • Callers can store the result in a ref readonly variable to maintain the readonly guarantee
  • If stored in a regular ref variable, the compiler creates a defensive copy
  • Particularly beneficial for large readonly structs to avoid copying overhead
  • The returned reference must have a lifetime that extends beyond the method

More information