Over the past few years, I’ve been using a lot of immutable objects in my code. What are immutable objects, you ask? An immutable object is an object whose state cannot be modified after it is created. For instance, here’s an immutable object:
public class ImmutablePoint { public int X { get; } public int Y { get; } public ImmutablePoint(int x, int y) { X = x; Y = y; } }
Once that object is created, it cannot be modified. A mutable object, on the other hand, can be modified after it is created:
public class MutablePoint { public int X { get; set; } public int Y { get; set; } public MutablePoint(int x, int y) { X = x; Y = y; } }
So why are immutable objects useful? Because they reduce bugs. For instance, look at this code:
public static MutablePoint CalculateSecondPoint(MutablePoint input) { var output = new MutablePoint(input.X+1, input.Y+1); return output; } var firstPoint = new MutablePoint(1,2); var secondPoint = CalculateSecondPoint(firstPoint); Console.WriteLine("Points: " + firstPoint.X + "," + firstPoint.Y + " - " + secondPoint.X + "," + secondPoint.Y);
What do you think this outputs? Answer:
Points: 1,2 - 2,3
Simple, right? But what if there’s a bug in CalculateSecondPoint?:
public static MutablePoint CalculateSecondPoint(MutablePoint input) { var output = new MutablePoint(input.X+=1, input.Y+1); return output; }
Now it outputs the wrong points:
Points: 2,2 - 2,3
So how do you prevent that bug? You use immutable objects:
public static ImmutablePoint CalculateSecondPoint(ImmutablePoint input) { var output = new ImmutablePoint(input.X+=1, input.Y+1); return output; } var firstPoint = new ImmutablePoint(1,2); var secondPoint = CalculateSecondPoint(firstPoint); Console.WriteLine("Points: " + firstPoint.X + "," + firstPoint.Y + " - " + secondPoint.X + "," + secondPoint.Y);
Now it won’t even compile — the “+=” in CalculateSecondPoint will cause a compiler error.
I realize that this is a somewhat contrived example. But based on my experience, using immutable objects does lead to more bug-free code.