为什么集合初始化表达式需要实现IEnumerable?

为什么会生成编译器错误:

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" }; } } 

但这不是:

 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" }; } } 

将集合初始值设定项(对于调用Add方法的语法糖)限制为实现没有Add方法且未使用的接口的类的原因是什么?

对象初始化器不会; 集合初始化程序。 这样它就可以应用于真正代表集合的类,而不仅仅是具有Add方法的任意类。 我必须承认,我经常明确地“实现” IEnumerable ,只是为了允许集合初始化器 – 但是从GetEnumerator()抛出了一个NotImplementedException

请注意,在C#3的开发早期,集合初始化程序必须实现ICollection ,但发现它过于严格。 Mads Torgersen在2006年发表了关于这一变化的博客 ,以及要求IEnumerable背后的原因。