Create Immutable Type in C#


How to create an immutable type in C#.


Create a class with:

  1. Fields: that are private and readonly.
  2. Constructors:
    1. Public: that accepts parameters to initialise the class
    2. Private: that accepts parameter for all the fields/properties of the class
  3. Properties: that are read-only.
  4. Methods: that return a new object (of same type) instead of mutating the state (fields/properties).

The test below shows that the old instance remains unchanged:


The idea behind immutable types is that once initialised, they don’t mutate their state and instead create & return a new object.

By making the fields read-only we ensure that once initialised in a constructor, they can’t be modified, even by the code in the class itself.

Public constructor that accepts initialisation data is required so that client can pass-in minimum state for the type to be valid. Private constructor, on the other hand, is used by methods to construct a new object and set all its state.

Properties must be made read-only by using get; only properties or expression-bodied functions. Note also the use of IReadOnlyList, this is to ensure that clients can’t add to lists. Methods will construct a new object based on current state.


Of course creating immutable types is extra work, so why and when should we use them?

I’ve found that Value Objects are good candidates for this. These are abstractions based on their values and therefore it doesn’t make sense for one object to “mutate” into another e.g. £5 note can’t become £10 note, each note (object) is defined by its value and is distinct.

I’ve also found them useful in writing library code that other developers use. E.g. if you’re building a library to connect to Azure NoSQL and have a class AzureNoSqlSettings that is being passed to this library, it is useful to make this settings class immutable so that it is clear to all developers (working on library) that settings object must not change once set by the client.

Immutable Types are also useful in concurrency scenarios since multiple threads are not mutating same fields/state.

Source Code


One comment

Leave a Reply