The “Structs Should Always be Immutable” Guideline

Sometimes one comes across the following guideline for C# structs:

All structs should be immutable.

The results of searching the web for justification for this are not very satisfying.

One argument sometimes advanced is that an immutable struct is usually simpler to understand than a mutable struct. This argument is true, but it also applies to classes, so it doesn’t explain why mutable classes should exist. Obviously we need mutable classes if the language is to be very useful as an object oriented language, so the simplicity argument for immutable structs has a major weakness.

A second argument is that making all structs immutable simplifies multithreaded applications, because it allows client code to be written without having to do the copying that is necessary with mutable structs:

void threadSafeMethod(mutableStruct s)
{
  mutableStruct t = s;
  (work with t)
}

This argument, too, is useful to know, and this argument, too, applies to classes and so is not a satisfying justification for why structs should be immutable.

A third argument for making structs immutable is that prominent value types are immutable, and many people will reason by analogy that structs should behave like the prominent exemplars of value types such as Int64 and Double. A struct that behaves differently would violate this expectation. This argument does not apply to classes and so may be somewhat more satisfying than the first two arguments.

A fourth argument for making structs immutable is to make it impossible to have a certain weird scenario where a boxed instance can be modified. This scenario violates reasonable client assumptions that values residing inside a box will not be modified. It is a satisfying argument because it does not apply to classes, since class instances cannot be boxed.

The weird scenario for modifying boxed values is described in Richter’s book, CLR via C#, Microsoft Press, 2006. Below is an adaptation.

using System;

interface IChangeable
  { void Change(int v); }

struct S : IChangeable
{
  int _v;

  public S(int v)
    { _v = v; }

  public void Change(int v)
    { _v = v; }

  public override string ToString()
    { return _v.ToString(); }
}

public class BoxingExample
{
  static void Main()
  {
    S s = new S(3);

    Object boxed = s;
    // One might expect the value in 'boxed'
    // to always be 3 after this point.

    ((IChangeable) boxed).Change(4);

    // But the next line prints "4"!!
    Console.WriteLine("boxed={0}", boxed);
  }
}

2 Responses to “The “Structs Should Always be Immutable” Guideline”

  1. The first argument ist very weak. I don’t really see how immutable types are supposed to be simpler. Is it simpler to always create new objects instead of changing existing ones?

    The second argument is plain wrong. In your example, s is already a copy of the argument passed to threadSafeMethod. There is no need for t at all because C# passes method arguments by value, unless you explicitly declare it a reference argument with the ref keyword. Which is required both in the argument list as well as at the call site, so it’s instantly obvious you’re dealing with a reference.

    The third argument is a matter of perspective. You may actually consider the primitive types mutable, given operators such as ++, +=, *=, etc.

    The fourth argument is based on a flawed assumption.
    “This scenario violates reasonable client assumptions that values residing inside a box will not be modified.”
    What is the reasoning behind this assumption to make it a “reasonable” one?

    The correct assumption is: when I’m dealing with a variable of type Object, or an interface variable (like boxed, cast to IChangeable in your example), I expect it to behave as if it refers to an instance of a reference type.

    IChangeable.Change _should_ change the instance it’s called on, whether that’s a boxed value type or a “real” reference type.

    Regards,
    Georg

  2. You came to bid me good bye, then you are just in time probably <a href="http://idisk.mac.com/freemoviesofmusclarl/Public/1/free-movies-of-musclar-lesbians.html" rel="nofollow">free movies of musclar lesbians</a> What did St John Rivers think of this earthly angel I naturally sagtdbuzini

Leave a Reply