> ## 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.

# C# Readonly Field

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.

```csharp theme={"dark"}
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.

```csharp theme={"dark"}
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.

```csharp theme={"dark"}
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`.

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor C# Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
