Understanding the readonly Keyword in C#

Understanding C# readonly with Value and Reference Types

In C#, the readonly keyword means a field can be assigned only once. Many developers interpret this as “unchangeable,” but it behaves quite differently for value types versus reference types.

This post explores how readonly behaves with both, and how references are fixed while their contents might still be mutable.

Readonly with Value Types

readonly int number = 10;
number = 20; // ❌ Compile-time error - cannot reassign

When applied to value types (like int, float, bool), readonly prevents the value from ever being changed after it’s set.

Since value types directly hold data, readonly locks the value itself.

Readonly with Reference Types

private readonly string[] wordList;

For reference types (like arrays or objects), readonly prevents the reference (memory address) from being reassigned. But the contents of that reference are still mutable.

Initialization in Constructor Only

public WordWarrior()
{
    wordList = new string[] { "apple", "banana" }; // ✅ Allowed in constructor
}

public void ResetWords()
{
    wordList = new string[] { "grape", "lemon" }; // ❌ Not allowed outside constructor
}

Readonly fields must be initialized inside the constructor and cannot be changed afterward.

Reference Reassignment is Blocked

readonly string[] currentWords = new string[] { "sun", "moon", "stars" };
string[] newWords = new string[] { "ocean", "mountain" };
currentWords = newWords; // ❌ Not allowed

You cannot assign a different object to a readonly reference. The address is fixed.

Internal Data is Still Mutable

wordList[0] = "updated"; // ✅ Allowed

The reference can’t change, but the data it points to can be modified freely. So readonly isn’t the same as immutability.

Key Takeaways

  • readonly prevents reassignment of a field once initialized.
  • With value types, it locks the actual value.
  • With reference types, it locks the address but not the internal state.
  • Only constructors can initialize readonly fields.

How Is It Different from const?

const values are fixed at compile time and must be simple types like numbers or strings. They must be initialized at declaration.

readonly allows initialization at runtime (in constructors) and supports more complex types like arrays or objects.

const string[] colors = { "red", "green" }; // ❌ Not allowed

Use const for truly fixed values. Use readonly for fixed references to objects whose internal state might change.

Summary

The readonly keyword is not just about preventing changes. For value types, it locks the value. For reference types, it locks the reference, not the object’s state. Use const for compile-time constants, and readonly when you need a one-time assignment for more complex types.

Popular posts from this blog

Understanding Arrays as Reference Types in C#

Setting Up a Basic Follow Camera with Cinemachine 3.x

How to Initialize Struct – C# Struct Initialization Guide