关于c#:为什么集合初始化表达式需要实现IEnumerable?

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

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

1
2
3
4
5
6
7
8
9
10
11
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" };
    }
}

但这并不是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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,但这被发现是限制性的。MadsTorgersen在博客中提到了这一变化,以及2006年要求IEnumerable的原因。