Collection initializers not doing what you expect

Let’s assume that you have a class that have a collection property and that you want the default for that collection to be to actually have a value. That class might look like this:

 1: class Foo
 2: {
 3:     public Foo()
 4:     {
 5:         this.Numbers = new List<int> { 4711 };
 6:     }
 7:     public ICollection<int> Numbers { get; set; }
 8: }

Now somewhere else in your code you want to override the collection value and set some other value so you do this:

 9: var foo= new Foo { Numbers = { 42 } };

So what is now the value of the property Numbers? Turns out it actually holds both the initial value and the new value rather than just the one value you want. The way to do it if you only want one value is this:

 9: var foo= new Foo { Numbers = new List<int> { 42 } };

One way to try and avoid this is to not initialize the Numbers property with a list but rather an array like this:

 5:         this.Numbers = new[] { 4711 };

But that might not always be possible so you might be better off by not exposing your collections like this and only provide an IEnumerable property for enumeration and do all manipulation through separate methods and not properties.

Comments (1)

  1. IEnumerable also used to show deferred execution and calculations "on demand". Multiple enumeration of IEnumerable is bad idea. Behind this interface can be database query, heavy calculations and etc. To separate "in memory" collections with safe multiple enumeration I use the IReadOnlyCollection / IReadOnlyList from System.Collections.Generic (new in .NET 4.5).