Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A readonly struct is a value type declared with the readonly modifier, which enforces strict immutability at the compiler level. When applied to a struct, the C# compiler guarantees that the state of the object cannot be modified after initialization, treating the hidden this reference as an in parameter for all instance members.
public readonly struct Vector2D
{
    // Fields must be explicitly marked readonly
    public readonly double X;
    
    // Auto-properties must be get-only or init-only
    public double Y { get; init; }

    public Vector2D(double x, double y)
    {
        X = x;
        Y = y;
    }
}

Compiler Rules and Constraints

Applying the readonly modifier to a struct imposes the following strict compilation rules:
  1. Instance Fields: Every instance field declared within the struct must be explicitly marked with the readonly keyword.
  2. Properties: Auto-implemented properties cannot have set accessors. They must be get-only or utilize init accessors.
  3. Constructors: As of C# 11, struct constructors no longer require explicit definite assignment of all fields before control leaves the constructor. The compiler automatically initializes any unassigned fields to their default values.
  4. Events: Field-like events are prohibited because the compiler automatically generates a mutable backing delegate field for them. To implement events in a readonly struct, you must explicitly define custom add and remove accessors.
  5. Static Members: The readonly constraint applies exclusively to instance state. Static fields and static properties within a readonly struct are not required to be readonly.

Mechanics of the this Reference

In a standard, non-readonly struct, the compiler passes the this reference to instance methods and property accessors as a ref parameter. This allows instance methods to mutate the struct’s internal state. In a readonly struct, the compiler alters the method signature of all instance members to pass the this reference as an in parameter (ref readonly).
public readonly struct Matrix
{
    public readonly int Value;

    public Matrix(int value) => Value = value;

    // The compiler treats 'this' as an 'in Matrix' parameter here
    public int Compute() => Value * 2; 
}
Because this is an in parameter, the compiler statically guarantees that no instance method can mutate the struct. Consequently, if a readonly struct is passed to another method via the in modifier, the compiler will not generate hidden defensive copies when invoking its instance members, as the immutability is already guaranteed at the type level.

Compilation Failures

Attempting to violate the immutability contract results in immediate compiler errors:
public readonly struct InvalidStruct
{
    // Error CS8340: Instance fields of a readonly struct must be readonly.
    public int MutableField; 

    // Error CS8341: Auto-implemented instance properties in a readonly struct must be readonly.
    public int MutableProperty { get; set; } 

    public readonly int State;

    public InvalidStruct(int state)
    {
        State = state;
    }

    public void AttemptMutation()
    {
        // Error CS0191: A readonly field cannot be assigned to (except in a constructor or a variable initializer).
        State = 42; 
    }
}
Master C# with Deep Grasping Methodology!Learn More