tags:

views:

337

answers:

5

I was just curious to know why structs, strings etc are immutable? What is the reason for making them immutable and rest of the objects as mutable. What are the things that are considered to make an object immutable?

Is there any difference on the way how memory is allocated and deallocated for mutable and immutable objects?

+7  A: 

Structs not...which is why mutable structs are evil.

Creating mutable structs can lead to all kinds of strange behavior in your application and, therefore, they are considered a very bad idea (stemming from the fact that they look like a reference type but are actually a value type and will be copied whenever you pass them around).

Strings, on the other hand, are. This makes them inherently thread-safe as well as allowing for optimizations via string interning. If you need to construct a complicated string on the fly, you can use StringBuilder.

Justin Niessner
Did you mean "mutable structs are evil"?
Martin Liversage
@Martin. Just making sure people are paying attention. Heh. Fixed.
Justin Niessner
He may have meant why structs and strings in the BCL are immutable (generally speaking, although I don't know of any mutable structs) rather than why *all* structs are immutable (which your answer correctly, um, corrects).
Anthony Pegram
@Anthony: Lots of `IEnumerator` implementations in the BCL are structs. E.g. http://msdn.microsoft.com/en-us/library/x854yt9s.aspx Don't expose one of them through a property, or suffer dire consequences. :)
Joren
+1  A: 

Structs can be mutable, but it's a bad idea because they have copy-semantics. If you make a change to a struct, you might actually be modifying a copy. Keeping track of exactly what has been changed is very tricky.

Mutable structs breed mistakes.

Strilanc
+2  A: 

This SO post should have all you need.

ck
+1  A: 

A struct type is not immutable. Yes, strings are. Making your own type immutable is easy, simply don't provide a default constructor, make all fields private and define no methods or properties that change a field value. Have a method that should mutate the object return a new object instead. There is a memory management angle, you tend to create a lot of copies and garbage.

Hans Passant
+7  A: 

If this subject interests you, I have a number of articles about immutable programming at http://blogs.msdn.com/b/ericlippert/archive/tags/immutability/

I was just curious to know why structs, strings etc are immutable?

Structs and classes are not immutable by default, though it is a best practice to make structs immutable. I like immutable classes too.

Strings are immutable.

What is the reason for making them immutable and rest of the objects as mutable.

Reasons to make all types immutable:

  • It is easier to reason about objects that do not change. If I have a queue with three items in it, I know it is not empty now, it was not empty five minutes ago, it will not be empty in the future. It's immutable! Once I know a fact about it, I can use that fact forever. Facts about immutable objects do not go stale.

  • A special case of the first point: immutable objects are much easier to make threadsafe. Most thread safety problems are due to writes on one thread and reads on another; immutable objects don't have writes.

  • Immutable objects can be taken apart and re-used. For example, if you have an immutable binary tree then you can use its left and right subtrees as subtrees of a different tree without worrying about it. In a mutable structure you typically end up making copies of data to re-use it because you don't want changes to one logical object affecting another. This can save lots of time and memory.

Reasons to make structs immutable

There are lots of reasons to make structs immutable. Here's just one.

Structs are copied by value, not by reference. It is easy to accidentally treat a struct as being copied by reference. For example:

void M()
{
    S s = whatever;
    ... lots of code ...
    s.Mutate();
    ... lots more code ...
    Console.WriteLine(s.Foo);
    ...
}

Now you want to refactor some of that code into a helper method:

void Helper(S s)
{
    ... lots of code ...
    s.Mutate();
    ... lots more code ...
}

WRONG! That should be (ref S s) -- if you don't do that then the mutation will happen on a copy of s. If you don't allow mutations in the first place then all these sorts of problems go away.

Reasons to make strings immutable

Remember my first point about facts about immutable structures staying facts?

Suppose string were mutable:

public static File OpenFile(string filename)
{
    if (!HasPermission(filename)) throw new SecurityException();
    return InternalOpenFile(filename);
}

What if the hostile caller mutates filename after the security check and before the file is opened? The code just opened a file that they might not have permission to!

Again, mutable data is hard to reason about. You want the fact "this caller is authorized to see the file described by this string" to be true forever, not until a mutation happens. With mutable strings, to write secure code we'd constantly have to be making copies of data that we know do not change.

What are the things that are considered to make an object immutable?

Does the type logically represent something that is an "eternal" value? The number 12 is the number 12; it doesn't change. Integers should be immutable. The point (10, 30) is the point (10, 30); it doesn't change. Points should be immutable. The string "abc" is the string "abc"; it doesn't change. Strings should be immutable. The list (10, 20, 30) doesn't change. And so on.

Sometimes the type represents things that do change. Mary Smith's last name is Smith, but tomorrow she might be Mary Jones. Or Miss Smith today might be Doctor Smith tomorrow. The alien has fifty health points now but has ten after being hit by the laser beam. Some things are best represented as mutations.

Is there any difference on the way how memory is allocated and deallocated for mutable and immutable objects?

Not as such. As I mentioned before though, one of the nice things about immutable values is that something you can re-use parts of them without making copies. So in that sense, memory allocation can be very different.

Eric Lippert
I think this what they say Crystal Clear...Thanks for such a detailed explanation...
Sandeep