Почему выражение инициализатора коллекции требует, чтобы 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 году.