How to Declare and Use Read-Only Fields in C
In C#, read-only fields allow you to create variables whose values can be assigned only during declaration or within a constructor. This article explains how to declare and initialize read-only fields, how they behave with both value and reference types, and how they differ from compile-time constants.
Declaring a Read-Only Field
To declare a read-only field, add the readonly modifier
before the field's data type. A readonly field can be
initialized directly at the point of declaration or inside the
constructor of the enclosing class.
public class Car
{
// Initialized at declaration
public readonly int Wheels = 4;
// Initialized in constructor
public readonly string Vin;
public Car(string vin)
{
Vin = vin; // Allowed
}
public void ChangeVin(string newVin)
{
// Vin = newVin; // Compile error: A readonly field cannot be assigned to here
}
}Static Read-Only Fields
If you want a read-only field that belongs to the type itself rather
than an instance, combine the static and
readonly keywords. Static read-only fields can be
initialized at declaration or inside a static constructor.
public class Configuration
{
public static readonly DateTime AppStartTime;
static Configuration()
{
AppStartTime = DateTime.UtcNow;
}
}Key Rules for Read-Only Fields
- Assignment Timing: Values must be assigned either at the point of declaration or inside the constructor (instance constructors for instance fields, static constructors for static fields).
- Context Restriction: You cannot reassign a read-only field from outside the class or from an instance method inside the class.
- Runtime Evaluation: Unlike compile-time constants,
the value of a
readonlyfield is determined at runtime, allowing you to pass values into constructors dynamically.
Difference Between
readonly and const
| Feature | readonly |
const |
|---|---|---|
| Evaluation Time | Runtime | Compile-time |
| Assignment Locations | Declaration or Constructor | Declaration only |
| Types Allowed | Any type | Primitive types, strings, enums, null |
| Static by Default | No (requires static
keyword) |
Yes (implicitly static) |
Read-Only Fields with Reference Types
When using readonly with a reference type, only the
memory address (reference) is immutable. The properties and data within
the referenced object can still be modified.
public class Team
{
public readonly List<string> Members = new List<string>();
public void Modify()
{
// Allowed: Modifying the object's state
Members.Add("Alice");
// Error: Cannot reassign the reference
// Members = new List<string>();
}
}To make the contents of a collection or complex object fully
immutable, use read-only collections (such as
ReadOnlyCollection<T> or
ImmutableArray<T>) rather than relying solely on the
readonly keyword.