Почему выражение инициализатора коллекции требует реализации IEnumerable? - PullRequest
31 голосов
/ 15 сентября 2010

Почему это приводит к ошибке компилятора:

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 Ответ

24 голосов
/ 15 сентября 2010

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

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

...