I have been reading a lot of literature lately surrounding Value Types & Reference Types, and their differences. This question surrounds the topic of mutability and immutability of value types.
Based on what I have read, it seems that value types in .NET should be written in such a fashion that they are immutable; that is, once they have been assigned a value, the value of that type in memory never changes. Only subsequent copies of the type may construct new instances in memory with new values based off the original. It would seem that mutability in .NET is evil.
To clarify the understanding of immutability (for my own sanity, and for others), I have demonstrated this below:
DateTime
and TimeSpan
are examples of immutable structs because once a value has been assigned to an instance, that instances value cannot change, this is evident through readonly properties:
DateTime dt = new DateTime();
DateTime newdt = dt.AddDays(2); // Okay, new value stored in newdt
newdt.Year = 1945; // Error, cannot write to readonly property
Immutability can however be confusing when looking ar primitive types such as Int32
, Double
or Char
, because the types appear to be mutable, but my gut feeling is that actually, immutability is handled transparently via the CLR; take for example the following operations (I've commented in some very basic x86 equivalent to understand how immutability is handled in terms of a primitive type)
int x = 0;
// xor eax, eax; 'clear register to 0
// push eax; 'push eax (0) onto the stack
x = 5;
// pop eax; 'pop stack (0) into eax
// mov eax, 5; 'eax = 5
// push eax; 'push eax (5) onto the stack
x++;
// pop eax; 'pop stack (5) into eax
// add eax, 1; 'eax = 5 + 1
// push eax; 'push eax (6) onto the stack
All well and good so far; Microsoft appear to be doing a good job of implementing immutability into their value types; but then we begin to find the bad apples, and suble nuances which make mutability look okay and lul developers into a false sense of security!
I'm talking about Point, Size, Rectangle (and a few others) in the System.Drawing namespace.
All of a sudden we're given the ability to mutate a value type by it's properties, and I have a theory as to why this is possible; take for example the following code
Point p = new Point();
p.X = 100;
p.Y = 200;
// Immutability (had it been implemented here) might infer the following usage
Point p = new Point(100, 200);
Point p2 = p.AddXY(200, 300);
However as stated I had a theory as to why these structures are mutable:
- Microsoft just wanted to make it easier to work with these structures.
- They are interoperable with native GDI/GDI+ calls, so their behavior was designed around their native C/C++ counterparts.
So finally my questions:
- Have I fully covered and understood immutability and mutability?
- Should developers aim to build immutable structs as a rule?
- When is it acceptable to build mutable structs?