What are Immutable types?

In C#, primarly we have two types of objects: reference type and value type. Value type objects always have default value and created on stack. When we assign value type variable to another variable, a new copy gets created. While reference type objects default to null and created on heap. Multiple variables can point to the same object, it means changing the value using one, will reflect accross variables. There is one more type called Nullable type which is similar to value type with additional capability to have no value if it is unassigned. You can learn more about from one of my previous posts here

A reference type can be categorized in two types : Mutable and Immutable. The plain english meaning is “Can Change” and “Cannot Change” respectively and which is same here as well.

It means an Immutable type object cannot be changed after it’s creation/initialization and if one tries to change, a new copy gets created (if allowed) and returned. In other words, it is a reference type but having value type semantics. String is one of the most used immutable types and it is provided by the .NET framework.

Normal class that we create, are mutable type. Let’s see an example

    class Program
    {
        static void Main(string[] args)
        {
            Person objPerson = new Person() { Name = "Brij", Age =32 };
            UpdatePerson(objPerson);
            Console.WriteLine(objPerson.Name);
            Console.ReadKey();
        }

        static void UpdatePerson(Person P)
        {
            P.Name += " Mishra";
        }
    }

    public class Person
    {
        public string Name { get; set; }

        public int Age { get; set; }
    }

So in this example the output will be Brij Mishra as the same object got changed. This class can also be modified as where we just provide the getter and the values then can be modified either at constructor or any other method inside the same class.

public class Person
{
    private string _name;
    public string Name { get { return _name; } }

    private int _age;
    public int Age { get { return _age; } }

    public Person(string name, int age)
    {
        this._name = name;
        this._age = age;
    }
}

Now to make it an immutable object, we have two options:

  1. Use Const
  2. Use Readonly

So I can make the class as

   public class Person
    {
        private readonly string _name;
        public string Name { get { return _name; } }

        private readonly int _age;
        public int Age { get { return _age; }  }

        public Person(string name, int age)
        {
            this._name = name;
            this._age = age;
        }
    }

Now once we create an instance of this class, it cannot be updated as all the properties are readonly. Even, we cannot update in another new method in the same class as in the previous example. We can use the Const instead of readonly but in that case, we will loose the ability to assign the value while object creation, instead we will have to provide the value at class definition. One more drawback, as const variable initialized at Class level itself, also called compile time constant so it would be same for all the instances of that type.

Now lets create another class address and have a List of Addresses in the class as

 public class Person
    {
        private List
<Address> _addresses;
        private readonly string _name;
        public string Name { get { return _name; } }

        private readonly int _age;
        public int Age { get { return _age; }  }

        public Person(string name, int age, List
<Address> addresses)
        {
            this._name = name;
            this._age = age;
            _addresses = addresses;
        }
        public List
<Address> Addresses { get { return _addresses; } }
    }

    public class Address
    {
        public string Address1 { get; set; }

        public string Address2 { get; set; }

        public string City { get; set; }

        public string State { get; set; }

        public string Zip { get; set; }
    }

As here the list of address has only get property exposed, it means we cannot replace the whole collection but certainly we can update the items from the list by adding and/or removing an item as

Person objPerson = new Person("Brij", 32, addresses);
objPerson.Addresses.Add(new Address());

Now, to make the Person class Immuatble, we need to change it as readonly collection as

public class Person
{
    private List
<Address> _addresses;
    private readonly string _name;
    public string Name { get { return _name; } }

    private readonly int _age;
    public int Age { get { return _age; }  }

    public Person(string name, int age, List
<Address> addresses)
    {
        this._name = name;
        this._age = age;
        _addresses = addresses;
    }

    public ReadOnlyCollection
<Address> Addresses { get { return _addresses.AsReadOnly(); } }
}

Now we wont be able to add or remove items from list. Still we have here one gap and using we can update any existing address object as Address is not a immutable type.

To make it immutable we will require to make all the properties readonly or const.

So to make an object immuatble, all the internal type used, should also be immutable and all the collection should be readonly.

C# 6 added a feature that says if we have a auto property with only a getter then it can be only initialized in constructor. Behaind the scene, it uses private readonly property as

public class Person
{
    public string Name { get; }

    public int Age { get; }
}

Here if we try to update the properties other than the constructor, it will throw an error stating that it is readonly.

Hope you all have enjoyed the post.

Cheers
Brij

Advertisements