What is the difference between const and readonly in C#?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
const and readonly both express immutability in C#, but they mean different things at different stages of execution. const is a compile-time constant baked into consuming code, while readonly is a runtime-assigned field that can be set once during initialization or construction.
const Means Compile-Time Constant
A const field must be assigned a value that the compiler can determine immediately.
Because the value is known at compile time, the compiler substitutes the literal directly into calling code.
That substitution is important. If another assembly references MaxRetries, it may embed the value 3 at compile time. Changing the library later without recompiling the consumer can leave old callers using the old constant value.
That is why const is best for values that are truly universal and stable, such as mathematical or protocol constants.
readonly Means Assigned Once at Runtime
A readonly field can be assigned:
- at declaration time
- in the constructor
- in a static constructor if it is
static readonly
This makes readonly much more flexible. The value is still immutable after construction, but it does not need to be a compile-time literal.
readonly also works with values computed at runtime:
That could never be a const, because DateTime.UtcNow is determined at runtime.
const Is Implicitly Static, readonly Is Not
This is a small but important difference. A const belongs to the type itself, not to each instance.
A has one fixed meaning for the whole type. B can differ per instance, but once each instance is constructed, its own B cannot change.
If you want one shared immutable runtime value, use static readonly.
Versioning and Public APIs
This is where the distinction becomes operationally important. Public const fields can be risky across assemblies because callers may inline the value. If you expect the value might change in future versions, prefer public static readonly.
This keeps callers reading the field from the assembly at runtime instead of baking the old value into their own build.
A practical rule:
- '
constfor values that are permanently fixed' - '
readonlyfor values that are immutable after initialization but may depend on runtime or versioning concerns'
Reference Types and Object State
A readonly reference means the field cannot point to a different object after initialization. It does not mean the object itself is immutable.
The Names field cannot be reassigned to a new list, but code can still add items to the existing list unless you choose an immutable collection type.
That subtlety matters when people assume readonly gives deep immutability. It does not.
Common Pitfalls
- Using
constfor public library values that may change later creates versioning surprises because consumers can inline the old value. - Expecting
readonlyto mean compile-time constant misses the fact that constructor-assigned values are allowed. - Forgetting that
constis implicitly static can make the type semantics less obvious to newer developers. - Assuming a
readonlyreference makes the referenced object immutable leads to accidental mutation bugs. - Using
constfor values that are really configuration or deployment choices makes the code less flexible than it should be.
Summary
- '
constis compile-time, literal, and implicitly static.' - '
readonlyis runtime-assigned once, usually in a declaration or constructor.' - Use
constfor true constants that should never vary. - Use
readonlyorstatic readonlywhen the value is immutable after initialization but not a compile-time literal. - For public APIs and libraries, prefer
static readonlyoverconstwhen future value changes are possible.

