When should use Readonly and Get only properties
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In C#, readonly and get-only properties solve related but different problems. readonly applies to fields, while a get-only property controls what callers can do through the public API. The right choice depends on whether you are protecting internal state, exposing a value without a setter, or building an immutable type.
readonly Protects a Field
A readonly field can be assigned only at declaration time or inside a constructor. After construction, the field reference cannot be changed.
This is useful when the object should keep the same backing value for its entire lifetime. The field-level guarantee is about implementation state inside the class.
It is also important to understand what readonly does not do. If the field refers to a mutable object, the object’s contents can still change.
You cannot replace _messages with a new list after construction, but you can still call _messages.Add(...). readonly freezes the reference, not the object graph.
A Get-Only Property Protects the Public API
A get-only property is about how the value is exposed to callers. It has no public setter, so outside code cannot assign to it directly.
This is often the clearest choice when you want a public value that is assigned during construction and then only read afterward. It communicates immutability at the API level much better than a public field would.
A get-only property can also be computed instead of stored.
There is no equivalent “computed field” pattern with readonly fields alone. That is one reason properties are the normal public surface in C#.
Use Both Together for Immutable Types
A common pattern is to keep internal state in readonly fields and expose it through get-only properties.
This gives you a strong internal guarantee and a clean external API.
When to Prefer One Over the Other
Use a readonly field when:
- the value is internal implementation state
- the reference should never be reassigned after construction
- you do not want direct public exposure
Use a get-only property when:
- callers should be able to read the value but not write it
- the value is part of the type’s public contract
- the value may be computed instead of stored
In most public-facing C# design, properties are preferred over exposing fields directly.
What About init Properties
Modern C# also has init accessors, which allow assignment during object initialization but not afterward.
That is a separate tool. It is useful when you want object-initializer syntax, but it does not replace the distinction between readonly fields and get-only properties.
Common Pitfalls
- Talking about
readonlyand get-only properties as if they were the same feature. - Assuming
readonlymakes a referenced object fully immutable. - Exposing fields publicly when a property would communicate intent more clearly.
- Forgetting that get-only properties can be computed and do not need backing storage.
- Using a property setter when construction-time assignment is the only valid mutation point.
Summary
- '
readonlyapplies to fields and prevents reassignment after construction.' - A get-only property exposes a value that callers can read but not set.
- '
readonlyprotects internal implementation state; get-only properties shape the public API.' - A
readonlyreference can still point to a mutable object. - Use both together when building immutable or mostly immutable types with a clean interface.

