Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp Language Specification.doc
Скачиваний:
13
Добавлен:
26.09.2019
Размер:
4.75 Mб
Скачать

7.6.10.5Выражения создания делегата

Выражение_создания_делегата используется для создания нового экземпляра типа_делегата.

выражение_создания_делегата: new тип_делегата ( выражение )

Аргументом выражения создания делегата должна быть группа методов, анонимная функция, динамический тип во время компиляции или значение типа_делегата. Если аргумент является группой методов, он определяет метод, а для метода экземпляра — объект, для которого создается делегат. Если аргументом является анонимная функция, он напрямую определяет параметры и тело метода целевого делегата. Если аргумент является значением, он определяет экземпляр делегата, для которого создается копия.

Если выражение имеет динамический тип во время компиляции, то выражение_создания_делегата динамически связано (§7.2.2), а правила внизу применяются во время выполнения с помощью типа времени выполнения выражения. Иначе правила применяются во время компиляции.

Во время прявязки обработка выражения_создания_делегата в виде new D(E), где D имеет тип_делегата, а E является выражением, включает следующие этапы.

  • Если E является группой методов, выражение создания делегата обрабатывается так же, как и преобразование группы методов (§6.6) из E в D.

  • Если E является анонимной функцией, выражение создания делегата обрабатывается так же, как и преобразование анонимной функции (§6.5) из E в D.

  • Если E является значением, то E должно быть совместимо (§15.1) с D, а результатом является новый созданный делегат типа D, который ссылается на тот же список вызова, что и E. Если E не совместимо с D, возникает ошибка времени компиляции.

Во время выполнения обработка выражения_создания_делегата в виде new D(E), где D имеет тип_делегата, а E является выражением, включает следующие этапы.

  • Если E является группой методов, выражение создания делегата обрабатывается как преобразование группы методов (§6.6) из E в D.

  • Если E является анонимной функцией, выражение создания делегата обрабатывается как преобразование анонимной функции из E в D (§6.5).

  • Если E является значением типа_делегата:

  • Вычисляется E. Если при этом вычислении возникает исключение, дальнейшие этапы не выполняются.

  • Если E имеет значение null, вызывается исключение System.NullReferenceException и дальнейшие этапы не выполняются.

  • Создается новый экземпляр типа делегата D. Если для создания нового экземпляра недостаточно памяти, то возникает исключение System.OutOfMemoryException и дальнейшие этапы не выполняются

  • Новый экземпляр делегата инициализируется с помощью того же списка вызова, что и экземпляр делегата, предоставленный E.

Список вызова делегата определяется при инициализации делегата и остается неизменным в течение всего срока жизни делегата. Другими словами после создания делегата изменить его целевые вызываемые сущности невозможно. При объединении двух делегатов или удалении одного из другого (§15.1) создается новый делегат. Содержимое существующих делегатов не меняется.

Нельзя создать делегат, который бы ссылался на свойство, индексатор, пользовательский оператор, конструктор экземпляра, деструктор или статический конструктор.

Как говорилось выше, когда делегат создается из группы методов, список формальных параметров и тип возвращаемого значения делегата определяют выбираемый перегруженный метод. В примере

delegate double DoubleFunc(double x);

class A { DoubleFunc f = new DoubleFunc(Square);

static float Square(float x) { return x * x; }

static double Square(double x) { return x * x; } }

поле A.f инициализируется с помощью делегата, который ссылается на второй метод Square, потому что этот метод в точности совпадает по списку формальных параметров и типу возвращаемого значения с DoubleFunc. Если бы второй метод Square отсутствовал, то возникла бы ошибка времени компиляции.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]