BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Making Immutable Object Graphs Easier in C#

Making Immutable Object Graphs Easier in C#

This item in japanese

Lire ce contenu en français

Creating a simple immutable class in C# is easy. You just need to create a constructor and fail to create public setters. But often that’s not enough. Eventually you may want to create deep graphs that, for efficiencies sake, should be created via a builder. Or perhaps you want to make non-destructive updates by creating methods that return a copy of the object with one field changed (e.g. the AddMinutes method on DateTime). Building out all these builders and methods can be quite tedious and thus error prone.

Andrew L Arnott has a solution that relies on T4 based code generators. T4, if you aren’t familiar with it, stands for Text Template Transformation Toolkit. This is at the core of Visual Studio’s code generation capabilities and libraries such as Entity Framework rely on it. The T4 scripts take a mutable class and create an immutable clone.

Andrew’s toolkit makes a somewhat controversial decision to not emit public constructors. Instead you are expected to use a static Create method or start with the Default instance and modify it from there. This is done using the WithXxx methods, for which there is one per property.

We can make a couple more enhancements though. For classes with many properties, if you need to change several properties at once, allocating a new object with each property change as an intermediate step is wasteful and can contribute to GC pressure. So we also add a With method that takes optional parameters for every property found on the class, allowing bulk property changes. Finally, for scenarios where you have several changes to make to the object but wish to do so in a multistep fashion (or just prefer property setters to With- method calls), we can construct a Builder class that allows mutation, and then can return the immutable copy when you’re done. This pattern is very similar to String and StringBuilder in the .NET Framework, and also like the recent immutable collections mentioned earlier.

Of course if you don’t like these decisions you can easily modify the T4 templates. Andrew intentionally broke up the templates into smaller file to make this easier. You can also add your own extensions without significantly changing the base templates.

Like all well written code generators, this one heavily uses partial methods. Partial methods allow developers to inject additional logic into code-generated methods without having to modify the generated file. For example, one can implement a method to set partial default values for the immutable object. Partial methods that aren’t implemented will be automatically stripped out by the compiler, thus incurring no runtime cost.

You can read more about Arron’s experiments with Immutable Object Graphs on his blog.

Rate this Article

Adoption
Style

BT