CodeOath
← All posts
C#65 min total · 17 parts

C# Fundamentals: Value Types, Reference Types, Boxing, and the Type System

Contents — Part 15 of 17: readonly struct and ref struct
Part 15 of 17 · ~1 min

readonly struct and ref struct

Two struct modifiers that make the immutability and stack-only guidance above enforceable by the compiler instead of just a convention:

readonly struct ImmutablePoint
{
    public readonly int X, Y;
    public ImmutablePoint(int x, int y) { X = x; Y = y; }
    // Any method that would mutate a field is a compile error inside a readonly struct
}

readonly struct makes every field implicitly readonly and disallows any method from mutating instance state — solving the mutable-struct trap above at the type-definition level, and as a bonus, it lets the compiler skip a defensive copy it would otherwise silently make when calling a member on a readonly field or parameter of a non-readonly struct type (a real, if obscure, performance detail: without readonly struct, the compiler can't prove a method call won't mutate the struct, so it copies first just in case).

ref struct SpanWrapper
{
    public Span<int> Data;
}

ref struct (used by Span<T> and ReadOnlySpan<T> in the base class library) is a struct that's guaranteed to live only on the stack — it can never be boxed, stored in a field of a non-ref struct class, captured by a lambda, or used across an await. That restriction is precisely what makes Span<T> safe to use as a zero-allocation view over contiguous memory (an array, a slice of a string, stack-allocated memory) without risking it outliving the memory it points into.