C# Immutability – What Are the Drawbacks of Immutable Types?

cimmutability

I see myself using more and more immutable types when the instances of the class are not expected to be changed. It requires more work (see example below), but makes it easier to use the types in a multithreaded environment.

At the same time, I rarely see immutable types in other applications, even when mutability wouldn't benefit anyone.

Question: Why immutable types are so rarely used in other applications?

  • Is this because it's longer to write code for an immutable type,
  • Or am I missing something and there are some important drawbacks when using immutable types?

Example from real life

Let's say you get Weather from a RESTful API like that:

public Weather FindWeather(string city)
{
    // TODO: Load the JSON response from the RESTful API and translate it into an instance
    // of the Weather class.
}

What we would generally see is (new lines and comments removed to shorten the code):

public sealed class Weather
{
    public City CorrespondingCity { get; set; }
    public SkyState Sky { get; set; } // Example: SkyState.Clouds, SkyState.HeavySnow, etc.
    public int PrecipitationRisk { get; set; }
    public int Temperature { get; set; }
}

On the other hand, I would write it this way, given that getting a Weather from the API, then modifying it would be weird: changing Temperature or Sky wouldn't change the weather in real world, and changing CorrespondingCity doesn't make sense neither.

public sealed class Weather
{
    private readonly City correspondingCity;
    private readonly SkyState sky;
    private readonly int precipitationRisk;
    private readonly int temperature;

    public Weather(City correspondingCity, SkyState sky, int precipitationRisk,
        int temperature)
    {
        this.correspondingCity = correspondingCity;
        this.sky = sky;
        this.precipitationRisk = precipitationRisk;
        this.temperature = temperature;
    }

    public City CorrespondingCity { get { return this.correspondingCity; } }
    public SkyState Sky { get { return this.sky; } }
    public int PrecipitationRisk { get { return this.precipitationRisk; } }
    public int Temperature { get { return this.temperature; } }
}

Best Answer

I program in C# and Objective-C. I really like immutable typing, but in real life I've been always forced to limit its usage, mainly for data types, for the following reasons:

  1. Implementation effort comparing to mutable types. With an immutable type, you would need to have a constructor requiring arguments for all properties. Your example is a good one. Try imagining that you have 10 classes, each having 5-10 properties. To make things easier, you might need to have a builder class to construct or create modified immutable instances in a manner similar to StringBuilder or UriBuilder in C#, or WeatherBuilder in your case. This is the main reason for me as many classes I design are not worth such an effort.
  2. Consumer usability. An immutable type is more difficult to use in comparison to mutable type. Instantiation requires initialising all values. Immutability also means that we cannot pass the instance to a method to modify its value without using a builder, and if we need to have a builder then the drawback is in my (1).
  3. Compatibility with the language's framework. Many of the data frameworks require mutable types and default constructors to operate. For example, you cannot do nested LINQ-to-SQL query with immutable types, and you cannot bind properties to be edited in editors such as Windows Forms' TextBox.

In short, immutability is good for objects that behave like values, or only have a few properties. Before making anything immutable, you must consider the effort needed and the usability of the class itself after making it immutable.