properties
readonly
get only
best practices
programming

When should use Readonly and Get only properties

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

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.

csharp
1public class UserSession
2{
3    private readonly Guid _sessionId;
4
5    public UserSession()
6    {
7        _sessionId = Guid.NewGuid();
8    }
9
10    public Guid SessionId => _sessionId;
11}

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.

csharp
private readonly List<string> _messages = new List<string>();

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.

csharp
1public class Order
2{
3    public int Id { get; }
4
5    public Order(int id)
6    {
7        Id = id;
8    }
9}

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.

csharp
1public class Rectangle
2{
3    public double Width { get; }
4    public double Height { get; }
5    public double Area => Width * Height;
6
7    public Rectangle(double width, double height)
8    {
9        Width = width;
10        Height = height;
11    }
12}

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.

csharp
1public class Person
2{
3    private readonly string _firstName;
4    private readonly string _lastName;
5
6    public string FirstName => _firstName;
7    public string LastName => _lastName;
8    public string FullName => $"{_firstName} {_lastName}";
9
10    public Person(string firstName, string lastName)
11    {
12        _firstName = firstName;
13        _lastName = lastName;
14    }
15}

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.

csharp
1public class Config
2{
3    public string Environment { get; init; } = "prod";
4}

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 readonly and get-only properties as if they were the same feature.
  • Assuming readonly makes 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

  • 'readonly applies to fields and prevents reassignment after construction.'
  • A get-only property exposes a value that callers can read but not set.
  • 'readonly protects internal implementation state; get-only properties shape the public API.'
  • A readonly reference can still point to a mutable object.
  • Use both together when building immutable or mostly immutable types with a clean interface.

Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.