为什么集合初始化表达式需要实现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
背后的原因。