Почему выражение инициализатора коллекции требует, чтобы 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 и который не используется?

Ответы

Ответ 1

Инициализатор объекта не работает; инициализатор коллекции. Это так, что оно применяется к классам, которые действительно представляют коллекции, а не просто произвольные, которые имеют метод Add. Я должен признать, что каждый так часто я "реализовал" IEnumerable явно, чтобы разрешить инициализаторы коллекции, но выбрал NotImplementedException из GetEnumerator().

Обратите внимание, что в начале разработки С# 3 инициализаторы коллекции должны были реализовать ICollection<T>, но это оказалось слишком ограничительным. Mads Torgersen написал об этом изменении и о причине необходимости IEnumerable, еще в 2006 году.