views:

148

answers:

4

Say I have a simple object such as

class Something
{
   public int SomeInt { get; set; }
}

I have read that using immutable objects are faster and a better means of using business objects? If this is so, should i strive to make all my objects as such:

class ImmutableSomething
{
   public int SomeInt { get { return m_someInt; } }
   private int m_someInt = 0;

   public void ChangeSomeInt(int newValue)
   {
       m_someInt = newvalue;
   }
}

What do you reckon?

+5  A: 

What you depict is not an immutable object; simply moving the set code into a dedicated setter method doesn't make an object immutable. An immutable object, by definition, can't change, so the fact that you can alter the value of any of the object's properties or fields means that it isn't immutable.

In terms of "faster" or "better", immutable objects are not intrinsically faster or "better" than mutable objects; there isn't anything special about them, other than the fact that you can't change any values.

Adam Robinson
I'd argue that immutable is "better" because from the client side of an immutable object, WYSIWYG. You know it's not going to unexpectedly change state when you call methods on it.
spender
@spender: Mutable objects and immutable objects can be "better" given a particular set of circumstances. Neither is "better" than the other as a general rule. You assert that having values change as the result of actions is a negative thing, which I don't believe is a valid generalization.
Adam Robinson
Ah i didn't realise that immutable meant a complete readonly object, thanks!
Daniel
I'm wearing my functional hat today. :) Ask me tomorrow and I'll change my mind... Hmm... Maybe I won't. Generally, the core concept of immutability in functional programming has really helped improve my procedural code.
spender
+1  A: 

That's not an immutable object. An immutable version of this would be something like

class ImmutableSomething : ISomething
{
    public readonly int SomeInt;

    public ImmutableSomething(int i)
    {
        SomeInt = i;
    }

    public ImmutableSomething AddValue(int add)
    {
        return new ImmutableSomething(this.SomeInt + add);
    }
}

The main benefit of an immutable object is that the object itself will never change, so you don't risk one part of your code changing the underlying values, especially in multithreading situations, but this applies in general. These guarantees often makes objects "better" in that you know what to expect, but there's nothing that makes immutables inherently "faster" than mutable objects.

For example, DateTimes are immutable, so you can do stuff like

DateTime someReferenceTime = DateTime.Now;

myBusinessLayer.DoABunchOfProcessingBasedOnTime(someReferenceTime);

// Here you are guaranteed that someReferenceTime has not changed, and you can do more with it.

Versus something like

StringBuilder sb = new StringBuilder("Seed");

myBusinessLayer.DoStuffBasedOnStringBuilder(sb);

// You have no guarantees about what sb contains here.
Tanzelax
That is also not truly immutable because the value SomeInt is still mutable even though the code is not excercised. Making it `readonly` is the best way to achieve immutability here
JaredPar
@JaredPar: Good point, changed to use `readonly`.
Tanzelax
+2  A: 

As others have said what you've posted isn't immutable. This is what an immutable object looks like. The readonly keyword means that the only place that the backing field for the property can be set is in the constructor. Essentially, after the object is constructed that's it forever.

public class ImmutableSomething
{
    private readonly int _someInt;
    public int SomeInt
    {
        get
        {
            return _someInt;
        }
    }

    public ImmutableSomething(int i)
    {
        _someInt = i;
    }

    public Add(int i){
        return new ImmutableSomething(_someInt + i);
    }
}

This is a big deal in functional programming because instead of talking about objects you get to talk about Values. Values never change, so you know that when you pass them to a function or method your original value will never be changed or updated. With mutable objects you can't make that guarantee.

Code built with immutable objects can be easily parallelized because there is no writable shared state. If some other thread gets your Value and wants to do something to it, it can't. "Changing" it in any way produces a new object with a brand new spot in memory just for that object.

So once you're dealing with values you can do some special things like interning which is what .NET does with strings. Because "Hello World" is a value and will never change, one reference to "Hello World" is just as good as any other, so instead of having "Hello World" in a hundred slots in memory, you have it in one slot and set all the references to "Hello World" to point to that one slot. So you get a big win on the memory side but you pay a performance penalty because whenever you create a new string you have to check the intern pool to make sure it doesn't already exist.

Jason Punyon
A: 

Leaving aside the point that the example doesn't actually show an immutable object, the main benefit for immutable objects is that they make certain multi-threaded operations dead simple and lock-free. For example, enumerating an immutable tree structure is possible without locks in a multi-threaded environment, whereas if the tree was mutable, you would need to introduce locks in order to safely enumerate it.

But there is nothing magical about immutable objects that makes them inherently faster.

Dean Harding