Why are mutable structs “evil”?
Structs are value types which means they are copied when they are passed around.
So if you change a copy you are changing only that copy, not the original and not any other copies which might be around.
If your struct is immutable then all automatic copies resulting from being passed by value will be the same.
If you want to change it you have to consciously do it by creating a new instance of the struct with the modified data. (not a copy)
Where to start ;-p
Eric Lippert's blog is always good for a quote:
This is yet another reason why mutable value types are evil. Try to always make value types immutable.
First, you tend to lose changes quite easily... for example, getting things out of a list:
Foo foo = list[0];
foo.Name = "abc";
what did that change? Nothing useful...
The same with properties:
myObj.SomeProperty.Size = 22; // the compiler spots this one
forcing you to do:
Bar bar = myObj.SomeProperty;
bar.Size = 22;
myObj.SomeProperty = bar;
less critically, there is a size issue; mutable objects tend to have multiple properties; yet if you have a struct with two int
s, a string
, a DateTime
and a bool
, you can very quickly burn through a lot of memory. With a class, multiple callers can share a reference to the same instance (references are small).
I wouldn't say evil but mutability is often a sign of overeagerness on the part of the programmer to provide a maximum of functionality. In reality, this is often not needed and that, in turn, makes the interface smaller, easier to use and harder to use wrong (= more robust).
One example of this is read/write and write/write conflicts in race conditions. These simply can't occur in immutable structures, since a write is not a valid operation.
Also, I claim that mutability is almost never actually needed, the programmer just thinks that it might be in the future. For example, it simply doesn't make sense to change a date. Rather, create a new date based off the old one. This is a cheap operation, so performance is not a consideration.