Как создать массивный конструктор C #, который позволит "new MyClass () {obj1, obj2, obj3};" - PullRequest
5 голосов
/ 29 марта 2011

Я пытаюсь создать класс, который принимает конструктор, похожий на конструктор словаря, списка или массива, где вы можете создать объект с буквальным набором объектов, хотя я не смог найти, как создать такойконструктор, если это вообще возможно.

MyClass obj = new MyClass()
{
    { value1, value2 },
    { value3, value4 }
}

Ответы [ 3 ]

10 голосов
/ 29 марта 2011

Вам нужно две вещи, чтобы заставить инициализаторы коллекции работать:

  1. Реализация IEnumerable (неуниверсальная версия)
  2. 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#

1 голос
/ 29 марта 2011

Как насчет конструктора переменных:

public class MyClass
{
    public MyClass() {}
    public MyClass(params object[] list) { ... }
}
0 голосов
/ 29 марта 2011

Не достаточно ли хорошо по умолчанию?

new MyClass {
   MyCol = {Value1, Value2, ... },
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...