Вам нужно две вещи, чтобы заставить инициализаторы коллекции работать:
- Реализация
IEnumerable
(неуниверсальная версия)
Add()
метод, соответствующий инициализатору коллекции
Вот пример, который выглядит как IDictionary:
class Program
{
static void Main(string[] args)
{
MyClass obj = new MyClass()
{
{value1, value2},
{value3, value4}
};
}
}
public class MyClass : IEnumerable
{
public void Add(object x, object y)
{
}
public IEnumerator GetEnumerator()
{
}
}
Обратите внимание, что код инициализатора коллекции буквально переводится так:
MyClass temp = new MyClass();
temp.Add(value1, value2);
temp.Add(value3, value4);
MyClass obj = temp;
Из-за временной переменной, если какой-либо из вызовов Add()
генерирует исключение, именованная переменная (в данном случае obj
) фактически никогда не назначается. Интересно, что это также означает, что если бы MyClass
должен был реализовать IDisposable
, то Dispose()
не был бы вызван для созданного объекта, когда один из Add()
методов генерирует ошибку (я проверял это, чтобы убедиться).
Зачем требуется IEnumerable
? Потому что этот интерфейс различает классы с Add
для коллекций и классы с Add
для вычислений.
http://blogs.msdn.com/b/madst/archive/2006/10/10/what-is-a-collection_3f00_.aspx
[когда вы анализируете классы с помощью Add
], вы понимаете, что по сути есть два принципиально разных значения имени «Добавить»:
a) Вставьте аргумент в коллекцию или
b) Вернуть арифметическую сумму аргумента и получателя
Также обратите внимание, что если ваш класс коллекции реализует IDisposable
, то вам не следует использовать инициализаторы коллекции, если есть вероятность, что Add()
сгенерирует исключение или если какое-либо из выражений, передаваемых в Add()
, может бросить исключение.
https://connect.microsoft.com/VisualStudio/feedback/details/654186/collection-initializers-called-on-collections-that-implement-idisposable-need-to-call-dispose-in-case-of-failure#