Update 2024-02-16:
Rereading this far into the future from when it was written is kind of prophetic. We would just use Record now in .NET but it’s still an interesting bit of history. In the article I refer to .NET 2 and 3 but obviously I’m referring to .NET framework.
Hopefully we all know string is immutable. When you type:
string x = "";
x = "asdf";
what you are really doing is creating two different strings, not changing the value, per se, of x but actually creating a new x.
That is why in heavy string operations it is recommended you use StringBuilder like:
StringBuilder sbName = new StringBuilder();
sbName.Append("asdf");
since appending to sbName doesn’t create a new string but continues to add to the string value of sbName.
So why do you care? Well, maybe you don’t. I’ve started to move into a more multi-threaded world where the state of objects and their properties could potientially be invalid if an external thread changes the value of a property. I’ve been reading Effective C# and More Effective C# and enjoying them. They are books that target specific development issues and paradigms that help you become a better C# developer. The books are written by Bill Wagner who is a regular blogger I follow.
Even though Effective C# came out in the .NET 2.0 days a lot of the book is still relevant, however, quite a few of the code samples could be updated.
Item 7 in Effective C# says “Prefer Immutable Atomic Value Types”. Now to paraphrase the chapter to an extreme it basically says, “Immutable code is easier to maintain”. I would add an addendum that whether you like it or not there is a good chance that code you write will be used in a multi-threaded environment and immutable will matter.
Now obviously to blindly say all classes must be like this is absurd. As Bill’s Item 7 says, however, “Prefer Immutable Atomic Value Types”.
In .NET 3.0 properties made things a bit easier in general. Prior to 3.0 for a property you would have to do:
private int _myInt;
public int MyInt
{
get { return _myInt; }
set { _myInt = value; }
}
In .NET 3.0 you don’t have to define the private. When the code is compiled it will take care of that for you. So the above code becomes:
public int MyInt { get; set; }
Now say you have to class:
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Address Address { get; set; }
public Customer(){}
}
If you were working in a multi-threaded environment you might have a problem if this happens:
public void HandleCustomerData(Customer MyCustomer)
{
MyCustomer.FirstName = "George";
//use myCustomer to do a bunch of stuff
MyCustomer.FirstName = "Joe";
//use myCustomer to do a bunch of stuff
}
This could cause a big problem if MyCustomer is getting passed around a lot in different threads. Now I know this is rather contrived but it is still a real issue.
Properties an additional feature here in 3.0 that makes things easier for creating an immutable. Imagine you have to class:
public class Customer
{
public string FirstName { get; private set; }
public string LastName { get; private set; }
public Address Address { get; private set; }
public Customer(string FirstName, string LastName, Address Address)
{
this.FirstName = FirstName;
this.LastName = LastName;
this.Address = Address;
}
}
You can see here that I’m using the private keyword on the set method. As it implies this forces the set methods of the properties to private so they can only be changed internally in the class. I would recommend reading “Effective C#” for a better explanation of why to use immutable values but by using the private in a property this becomes easier.
So there it is, prefer immutable atomic values in your classes and use the private keyword to help you.
Later,
Brian
Update:
The more I read this the more I think I over-simplified Bill’s reason for preferring immutable atomic value types. Just get the book and read it. It’s a fairly small book but every nugget has value.