Why does this generate a compiler error:
class X { public void Add(string str) { Console.WriteLine(str); } } static class Program { static void Main() { // error CS1922: Cannot initialize type 'X' with a collection initializer // because it does not implement 'System.Collections.IEnumerable' var x = new X { "string" }; } }
but this doesn’t:
class X : IEnumerable { public void Add(string str) { Console.WriteLine(str); } IEnumerator IEnumerable.GetEnumerator() { // Try to blow up horribly! throw new NotImplementedException(); } } static class Program { static void Main() { // prints “string” and doesn’t throw var x = new X { "string" }; } }
What is the reason for restricting collection initializers — which are syntactic sugar for a call to an Add
method — to classes that implement an interface which doesn’t have an Add
method and which isn’t used?
Collection initializers let you specify one or more element initializers when you initialize a collection type that implements IEnumerable and has Add with the appropriate signature as an instance method or an extension method. The element initializers can be a simple value, an expression, or an object initializer.
Type Initializers are a new language construct that allow for C# (and VB using similar syntax) to shortcut creating of custom constructors or writing additional code to initialize properties.
An object initializer is an expression that describes the initialization of an Object . Objects consist of properties, which are used to describe an object. The values of object properties can either contain primitive data types or other objects.
An object initializer doesn't; a collection initializer does. It's so that it's applied to classes which really represent collections, rather than just arbitrary ones which have an Add
method. I have to admit that every so often I've "implemented" IEnumerable
explicitly, just to allow collection initializers - but thrown a NotImplementedException
from GetEnumerator()
.
Note that early in C# 3's development, collection initializers had to implement ICollection<T>
, but that was found to be too restrictive. Mads Torgersen blogged about this change, and the reason behind requiring IEnumerable
, back in 2006.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With