yas4891
yas4891

Reputation: 4862

How to efficiently implement immutable types

When coding C# I often find myself implementing immutable types. I always end up writing quite a lot of code and I am wondering whether there is a faster way to achieve it.

What I normally write:

public struct MyType
{
  private Int32 _value;
  public Int32 Value { get { return _value;} }

  public MyType(Int32 val)
  {
     _value = val;
  }
}

MyType alpha = new MyType(42);

This gets fairly complicated when the number of fields grows and it is a lot of typing. Is there a more efficient way for doing this?

Upvotes: 5

Views: 456

Answers (3)

alf
alf

Reputation: 18540

Code snippets at the rescue! Save this xml as "immutable.snippet", then go to Visual Studio, select Tools, Code Snippets Manager and import it. That's it! Now write "immutable" and hit TAB twice and you have your immutable type.

The actual code in the snippet is based on @adrianbanks answer.

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
      <Title>Immutable type (C#)</Title>
      <Author>Alfonso Cora</Author>
      <Description>Creates an immutable type</Description>
      <HelpUrl>http://stackoverflow.com/questions/7236977/how-to-efficiently-implement-immutable-types</HelpUrl>
      <Shortcut>immutable</Shortcut>
    </Header>
    <Snippet>
      <Declarations>
        <Literal Editable="true">
          <ID>type</ID>
          <ToolTip>The type on which this immutable type is based.</ToolTip>
          <Default>int</Default>
          <Function>
          </Function>
        </Literal>
        <Literal Editable="true">
          <ID>class</ID>
          <ToolTip>The name of the immutable type.</ToolTip>
          <Default>MyImmutableType</Default>
          <Function>
          </Function>
        </Literal>
      </Declarations>
      <Code Language="csharp"><![CDATA[public sealed class $class$
{
    public $type$ Value{get {return _value;}}
    private readonly $type$ _value;

    public $class$($type$ value)
    {
        _value = value;
    }
}]]></Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

Upvotes: 1

adrianbanks
adrianbanks

Reputation: 82944

The only way I can suggest of writing less code is to use something like ReSharper to auto-generate the code for you. If you start with something like:

public class MyType
{
    private int _value;
}

you can then generate "read-only properties" to give:

public class MyType
{
    private int _value;
    public int Value{get {return _value;}}
}

followed by generate constructor to give:

public class MyType
{
    private int _value;
    public int Value{get {return _value;}}

    public MyType(int value)
    {
        _value = value;
    }
}

The generation steps are 8 key presses in total.


If you really want an unmodifiable immutable class, I would declare it as such:

public sealed class MyType
{
    public int Value{get {return _value;}}
    private readonly int _value;

    public MyType(int value)
    {
        _value = value;
    }
}

This makes the class non-derivable (meaning that a sub-class cannot modify its inner state), and the _value property assignable only during construction. Unfortunately, ReSharper doesn't have code generation for this pattern, so you would still have to construct (most of) it manually.

Upvotes: 5

Coding Flow
Coding Flow

Reputation: 21881

You could simplify it a little with automatic properties and a private setter as below:

public struct MyType
{  
  public Int32 Value { get; private set; }

  public MyType(Int32 val)
  {
     Value = val;
  }
}

Upvotes: 4

Related Questions