I was looking at C# collection initializers and found the implementation to be very pragmatic but also very unlike anything else in C#
I am able to create code like this:
using System; using System.Collections; class Program { static void Main() { Test test = new Test { 1, 2, 3 }; } } class Test : IEnumerable { public IEnumerator GetEnumerator() { throw new NotImplementedException(); } public void Add(int i) { } }
Since I have satisfied the minimum requirements for the compiler (implemented IEnumerable and a public void Add) this works but obviously has no value.
I was wondering what prevented the C# team from creating a more strict set of requirements? In other words why, in order for this syntax to compile, does the compiler not require that the type implement ICollection? That seems more in the spirit of other C# features.
Your observation is spot on – in fact, it mirrors one made by Mads Torgersen, a Microsoft C# Language PM.
Mads made a post in October 2006 on this subject titled What Is a Collection? in which he wrote:
It turns out that there are only 14 implementations of
ICollection<T>in the framework, but 189 classes that implementIEnumerableand have a publicAdd()method.There’s a hidden benefit to this approach – if they had based it on the
ICollection<T>interface, there would have been exactly one supportedAdd()method.In contrast, the approach they did take means that the initializers for the collection just form sets of arguments for the
Add()methods.To illustrate, let’s extend your code slightly:
You can now write this: