Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Value Types, Immutability (Good) & Mutability (Evil) in .NET [duplicate]

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:

  1. Microsoft just wanted to make it easier to work with these structures.
  2. They are interoperable with native GDI/GDI+ calls, so their behavior was designed around their native C/C++ counterparts.

So finally my questions:

  1. Have I fully covered and understood immutability and mutability?
  2. Should developers aim to build immutable structs as a rule?
  3. When is it acceptable to build mutable structs?
like image 564
Matthew Layton Avatar asked Sep 01 '14 08:09

Matthew Layton


1 Answers

The issue of mutability is not one of value vs reference type. There are examples for both. Take System.String as an example for an immutable class as well as your example of System.Drawing.Point as an example of a mutable struct.

Mutable vs. immutable is a design decision based on the usage of the type. Whether it's a reference or a value type is another design decision that is not dependent on the former.

like image 74
nvoigt Avatar answered Sep 27 '22 20:09

nvoigt