Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a collection initializer expression require IEnumerable to be implemented?

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?

like image 800
Timwi Avatar asked Sep 15 '10 10:09

Timwi


People also ask

How to use collection initializer in c#?

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.

What is type initializer in C#?

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.

What is an object initializer?

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.


1 Answers

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.

like image 124
Jon Skeet Avatar answered Sep 20 '22 02:09

Jon Skeet