BT
x Your opinion matters! Please fill in the InfoQ Survey about your reading habits!

.NET Immutable Collections Ready for Production

by Jonathan Allen on Sep 27, 2013 |

With the exception of ImmutableArray, Microsoft’s Base Class Library team has completed their production version of .NET’s Immutable Collections. Along with it are design guidelines for other types of immutable objects.

Immutable Collections are designed for situations where you want to be able to safely share collections across multiple threads, but still allow each thread to make its own changes if necessary. Unlike a read-only collection, which has to be copied in its entirety, new immutable collections can be created from existing ones relatively cheaply.

Care has to be used when working with immutable collections, for it is really easy to write “list.Add(item)” instead of “list = list.Add(item)”. Even the compiler can make this mistake, which is why immutable collections don’t have constructors. Consider this code:

list = new ImmutableList<int> {1, 2, 3};

At compile this this would become…

temp = new ImmutableList<int>();
temp.Add(1);
temp.Add(2)
temp.Add(3)
list = temp;

With the result of the three Add operations being thrown away, list has a count of 0 instead of the expected 3.

Guidelines for Immutable Objects

When creating your own immutable objects, Immo Lendwerth recommends creating WithXxx methods. For simple objects there would be one WithXxx method for each property. The method would return a copy with the object with the indicated property changed.

If the property represents a collection the pattern is slightly different. Here is an example from Immo’s announcement:

As you can see, the WithLines can accept any IEnumerable. This allows you to pass it either a new ImmutableList or the result of a LINQ expression. While this can be effective on its own, he also recommends some extra convenience methods.

ImmutableArray Pulled

The ImmutableArray class was pulled from the final release because of performance problems. In order to satisfy their memory performance goals, the ImmutableArray had to be a value type. And keeping with value type semantics, a default instance of ImmutableArray should behave like an empty array. Unfortunately the null check needed to make this happen was preventing C# from eliminating the array bounds check, an important consideration when trying to achieve good CPU performance.

Since the ImmutableArray class is very important to the Roslyn compiler project, they considered removing the null checks that were causing the performance hit. But that resulted in other problems. Immo writes,

Since all value types have an automatic default constructor that initializes the value type to its default state, empty will be an ImmutableArray<T> whose underlying array is null. Thus, the implementation of AddRange will crash with a NullReferenceException.

There are other places where this problem manifests itself. Since ImmutableArray<T> implements certain collection interfaces (such as IEnumerable and IReadOnlyList), you can pass it to methods that work against the interface. Since the interface reference will be non-null, consumers won’t expect any methods or property invocations to cause a NullReferenceException.

The Base Class Library team haven’t given up on the project and are continuing to look at design options to reintroduce the ImmutableArray.

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread
Community comments

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Discuss

Educational Content

General Feedback
Bugs
Advertising
Editorial
InfoQ.com and all content copyright © 2006-2014 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT