Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
My_shpory_Ivan_Ivanich (2).docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
149.35 Кб
Скачать

19. Делегаты, цепочка вызова

Делегат – это тип, который представляет собой ссылки на методы с определенным списком параметров и возвращаемым типом. При создании экземпляра делегата этот экземпляр можно связать с любым методом с совместимой сигнатурой и возвращаемым типом. Метод можно вызвать (активировать) с помощью экземпляра делегата.

Делегаты используются для передачи методов в качестве аргументов к другим методам. Обработчики событий — это нe что иное, как методы, вызываемые с помощью делегатов. Вы создаёте свой метод, и класс, как например, элемент управления Windows, может вызывать ваш метод при возникновении определенного события. В следующем примере показано объявление делегата: public delegate int PerformCalculation(int x, int y);

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

Благодаря возможности ссылаться на метод как на параметр, делегаты оптимально подходят для задания функций обратного вызова. Например, ссылка на метод, сравнивающий два объекта, может быть передана в качестве аргумента алгоритму сортировки. Поскольку код сравнения находится в отдельной процедуре, алгоритм сортировки может быть написан более общим способом.

Делегаты имеют следующие свойства.

  • Делегаты похожи на указатели функций в C++, но являются типобезопасными.

  • Делегаты позволяют производить передачу методов подобно обычным параметрам.

  • Делегаты можно использовать для определения методов обратного вызова.

  • Делегаты можно связывать друг с другом; например, при появлении одного события можно вызывать несколько методов.

  • Точное соответствие методов типу делегата не требуется. 

  • В C# 3.0 для краткой записи встроенных блоков кода введены лямбда-выражения. В результате компиляции как анонимных методов, так и лямбда-выражений (в определенном контексте) получаются типы делегатов. В настоящее время эти возможности называются анонимными функциями.

Цепочка вызовов

Групповая адресация

Одним из самых примечательных свойств делегата является поддержка групповой адресации. Попросту говоря, групповая адресация — это возможность создать список, или цепочку вызовов, для методов, которые вызываются автоматически при обращении к делегату. Создать такую цепочку нетрудно. Для этого достаточно получить экземпляр делегата, а затем добавить методы в цепочку с помощью оператора + или +=. Для удаления метода из цепочки служит оператор - или -=. Если делегат возвращает значение, то им становится значение, возвращаемое последним методом в списке вызовов. Поэтому делегат, в котором используется групповая адресация, обычно имеет возвращаемый тип void.

Del delObject = method1;

delObject += method2;

delObject -= method1;

20. Асинхронный вызов с помощью объекта делегата

Перед использованием асинхронного делегата следует помнить, что все типы делегатов автоматически предоставляют два метода по имени BeginInvoke и EndInvoke. Сигнатуры этих методов основаны на сигнатуре типа делегата, содержащего их. Например, следующий тип делегата:

delegate int MyDelegate(int x, int y)

предоставляет следующие методы согласно генерации компилятора:

IAsyncResult BeginInvoke(int x, int y, AsyncCallback callback, object object, IAsyncResult result); int EndInvoke (IAsyncResult result);

Эти два метода генерируются компилятором. Чтобы вызвать метод асинхронно, сначала надо сослаться на него с помощью объекта делегата, имеющего такую же сигнатуру. Затем надо вызвать BeginInvoke для этого объекта делегата. Компилятор следит, чтобы первыми аргументами метода BeginInvoke были аргументы вызываемого метода. Последние два аргумента этого метода, IAsyncResult и object, будут рассмотрены кратко. Возвращаемое значение асинхронного вызова извлекается путем вызова метода EndInvoke. Тут компилятор тоже следит, чтобы возвращаемое значение EndInvoke было точно таким же, как и возвращаемое значение типа делегата (в данном примере это тип int). Вызов EndInvoke блокирующий, то есть вызов вернет управление только при завершении асинхронного выполнения. Следующий пример показывает асинхронный вызов метода ShowSum:

TheDelegate d = ShowSum;   IAsyncResult ar = d.BeginInvoke(10, 10, null, null);   int sum = d.EndInvoke(ar);

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