Immutable type and property in C#

An immutable type is a type of which its properties can only be set at initialization. Once an object is created, nothing can be changed anymore. An immutable property is simply a read-only property.

In the following example, ImmutableType is an immutable type with one property Test. Test is a read-only property. It can only be set at construction.

class ImmutableType
{
    private readonly string _test;
    public string Test
    {
        get { return _test; }
    }

    public ImmutableType(string test)
    {
        _test = test;
    }
}

See also: The Wikipedia article, and some Stack Overflow questions on the topic.


In addition to @fretje's answer above, in C#6 and later, getter-only auto properties have now been implemented, which allows for immutable auto-properties without the need for the additional explicit private readonly backing field. The equivalent code would be abbreviated to:

class ImmutableType
{
    public string Test
    {
        get; // No Set at all, not even a private set.
    }

    public ImmutableType(string test)
    {
        Test = test; // The compiler understands this and initializes the backing field
    }
}

Note that private set only provides a restricted encapsulation of change to the property from within the same class, and thus isn't truly immutable:

public string Test
{
    get;
    private set;  // Not immutable, since this is still mutable from within the class
}

More about immutability

As others have said, an immutable Property is a property which cannot change once it has been set. Setting of the 'only' value is done during construction.

An immutable Type is a type where all (externally visible) properties and fields are immutable - for example the "Record" Type originally scheduled for C#7 (hopefully now 8) would have been an immutable type. Other examples of Immutable Types are Tuples, and all anonymous classes.

Immutable fields should be qualified with the readonly keyword in C# - this is enforced by the compiler to ensure that no other code attempts to change the field outside of the constructor.

Wherever possible, immutability of fields, variables and properties is regarded as good practice, as this greatly reduces the surface area for bugs (since fields represent the state of an object, preventing change to fields reduces the number of states).

The benefit of immutability is especially important in multi-threaded programs, where two or more threads concurrently access the same object. Since multiple concurrent reading threads can safely read the value of a field or property, the programmer doesn't need to be concerned about thread safety issues relating to change to the field by other threads (because change to the property is prohibited)

One common drawback of immutability when dealing with complex objects consisting of multiple composed objects, is that the entire graph needs to be built 'in one go', which can lead to messy code. A common solution here is to use the Builder pattern as a scaffold, which allows a transient, mutable representation to be built in steps, and then the final, immutable object is obtained in the final .Build() step.