views:

165

answers:

2

I like the immutability concept but sometimes I wonder, when an application isn't meant to be parallel, should one avoid making things immutable?

When an application isn't multi-threaded, you aren't plagued by shared state problems, right?

Or is immutability a concept like OOP that you either use all the way or not? Excluding the cases when something shouldn't be immutable based on use/performance, etc.

I am faced with this question when writing an application for myself, that is moderately big (maybe like 1-2k lines).

+5  A: 

I like the advantage from immutability that you need to validate it only once - at creation of object. That's a huge bonus actually.

Arnis L.
Good point. This idea also has security implications. Suppose you pass a mutable object X to method Foo. Foo checks X to ensure that X is a valid argument to Foo, throws if it is not, and then makes some security-sensitive operation based on X. If a hostile caller can mutate X on another thread after the argument check, the argument check can effectively be bypassed! This is one reason why strings are immutable in .NET -- you want to be able to say "open this file", do a security check on that path, and know that the path string will not change between the check and the file open.
Eric Lippert
To do this, one is to use static factory pattern ... synchronized.
Nicholas Jordan
+6  A: 

I love immutability because it means I don't have to trust other peoples code not to mess around with objects I expect to stay the same.

When you pass an object off to another component such as a List<T>, you are at the mercy of what that component does. This is especially important when you return collections as properties.

public class Foo { 
  private List<Bar> _barList;
  public ICollection<Bar> BarList { get return _barList; } 
}

There's nothing stopping a consumer of this class from clearing the collection out from under me. Even switching the return type to IEnumerable<Bar> is not entirely safe. There's nothing stopping some piece of badly written code from casting this back to List<T> and calling .Clear().

However if I really want the collection to stay consistent I could rewrite it as followis

public class Foo {
  private ImmutableCollection<Bar> _barList;
  public ImmutableCollection<Bar> BarList { get { return _barList; } }
}

Now I'm safe from having to trust other code from using my class incorrectly. They can't mess it up.

JaredPar
Is ImmutableCollection in BCL? Or just an example?
Joan Venge
@Joan, it's from a library that I own. It's available at http://code.msdn.microsoft.com/BclExtras
JaredPar
Thanks Jared, will download it.
Joan Venge
You could also return List<T>.AsReadOnly(), which is built into the BCL.
Joe White
@Joe, Unfortunately ReadOnly collection is not immutable, it is merely read only. http://blogs.msdn.com/jaredpar/archive/2008/04/22/api-design-readonlycollection-t.aspx
JaredPar
@Joan, there's ReadOnlyCollection<T> in the framework if you don't want to roll your own. If when you construct it you throw away the List<T> you used to construct it, it will be immutable since there won't be any references around to the writeable internals of it. I agree with Jared that this can be a "gotcha" if you aren't on the look-out, though, and encapsulating this "create and throw away the List<T>" business could be useful.
Doug McClean