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 field in C# is a variable modifier that restricts assignment to the field strictly to its declaration or within the constructor(s) of the class or struct in which it is defined. Once the constructor finishes execution, the value or reference held by the readonly field becomes immutable for the lifetime of the object.
public class Configuration
{
    // Assignment at declaration
    public readonly int MaxRetries = 3;

    // Assignment deferred to constructor
    public readonly string Environment;

    public Configuration(string environment)
    {
        Environment = environment; // Valid assignment
    }

    public void UpdateEnvironment()
    {
        // Environment = "Production"; // Compiler error CS0191
    }
}

Technical Mechanics

Run-time Evaluation Unlike const fields, which are evaluated at compile-time and substituted directly into the Intermediate Language (IL) code, readonly fields are evaluated at run-time. This allows a readonly field to be initialized with dynamic data, such as the result of a method call, a system variable, or a constructor parameter. Scope and Modifiers By default, a readonly field is an instance member, meaning each instance of the class possesses its own copy of the field. It can be combined with the static modifier (static readonly). A static readonly field belongs to the type itself and must be initialized either at the point of declaration or within a static constructor.
public class Database
{
    // Evaluated once per application domain at run-time
    public static readonly long StartupTicks = DateTime.UtcNow.Ticks;
    
    static Database()
    {
        // Valid assignment for static readonly
        StartupTicks = DateTime.UtcNow.Ticks; 
    }
}

Shallow Immutability

The readonly keyword enforces shallow immutability. The behavior depends strictly on whether the field is a value type or a reference type:
  1. Value Types (struct, int, bool): The actual data is stored directly in the field. Because the field cannot be reassigned, the data itself is entirely immutable.
  2. Reference Types (class, List<T>, arrays): The field stores a memory reference to an object on the heap. The readonly modifier prevents the field from being reassigned to point to a different object. However, it does not protect the internal state of the referenced object from being mutated.
public class Cache
{
    public readonly List<string> Items = new List<string>();

    public void AddItem(string item)
    {
        // Valid: Mutating the internal state of the referenced object
        Items.Add(item); 
        
        // Invalid: Attempting to reassign the reference itself
        // Items = new List<string>(); // Compiler error CS0191
    }
}

Structs and Defensive Copies

When a readonly field holds a mutable struct, accessing its members can cause the C# compiler to generate a “defensive copy” of the struct to guarantee that the original readonly field is not mutated. To prevent the performance overhead of defensive copying, structs assigned to readonly fields should ideally be declared as readonly struct.
Master C# with Deep Grasping Methodology!Learn More