пользователей: 30398
предметов: 12406
вопросов: 234839
Конспект-online
РЕГИСТРАЦИЯ ЭКСКУРСИЯ

Делегаты в C#, назначение и использование делегатов. Использование делегатов для обратного вызова статических методов.

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

Делегаты используются для передачи методов в качестве аргументов к другим методам. Обработчики событий — это ничто иное, как методы, вызываемые с помощью делегатов. При создании пользовательского метода класс (например, элемент управления Windows) может вызывать этот метод при появлении определенного события. В следующем примере показано объявление делегата:

public delegate int PerformCalculation(int x, int y);

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

 

Методы обратного вызова повсеместно используются в Windows для передачи указателя функции другой функции, чтобы последняя могла вызвать первую (через переданный ей указатель). Так, функция Win32 API 
EnumWindows перечисляет все окна верхнего уровня на экране и для каждого окна вызывает переданную ей функцию. Обратные вызовы применяют по-разному, но наиболее распространены два случая.

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

·       Введение дополнительного кода в код класса Другой распространенный способ применения методов обратного вызова имеет место, когда класс позволяет клиенту указать метод для дополнительной нестандартной обработки. Например, в классе Windows Listbox можно указать нисходящий или восходящий порядок сортировки элементов. Кроме еще некоторых базовых возможностей для сортировки, этот класс на самом деле не дает полной свободы действий и остается общим классом. Но при этом Listbox позволяет указывать для сортировки функцию обратного вызова. Таким образом, Listbox для сортировки вызывает функцию обратного вызова, и ваш код может выполнять нужные нестандартные действия. 

Рассмотрим пример определения и применения делегата. В этом примере у нас есть класс менеджера базы данных, который отслеживает все активные соединения с БД и предоставляет метод перечисления этих соединений. Если допустить, что менеджер БД находится на удаленной машине, правильным решением будет сделать метод асинхронным, позволив клиенту предоставлять метод обратного вызова. Заметьте: в реальном приложении вам следовало бы задействовать многопоточность, чтобы добиться подлинной асинхронности. Но для упрощения примера и поскольку мы не рассматривали многопоточность, пока не будем ее применять. 
Для начала определим два главных класса: DBManager n DBConnection.

 

class DBConnection <
 

}
 

class DBManager { static DBConnection[]   activeConnections;
 

public delegate void   EnumConnectionsCallback(DBConnection
 

connection); public static void   EnumConnections(EnumConnectionsCallback
 

callback) {
 

foreach (DBConnection connection in   activeConnections)
 

{
 

callback(connection);
 

} > }

Метод EnumConnectionsCallback является делегатом, что определяется ключевым словом delegate в начале сигнатуры метода. Как видите, этот делегат возвращает void и принимает единственный аргумент — объект DBConnection. Метод EnumConnections в соответствии с его определением принимает единственный аргумент — метод EnumConnectionsCallback. Чтобы вызвать метод DBManager.EnumConnections нам нужно лишь передать ему экземпляр делегата DBManager.EnumConnectionCallback. 
Для создания экземпляра делегата нужно применить new, передав ему имя метода, имеющего ту же сигнатуру, что и у делегата. Вот пример:

DBManager.EnumConnectionsCallback myCallback =
 

new DBManager.EnumConnectionsCallback(ActiveConnectionsCallback);
 

DjlManager.EnumConnections(myCallback);
 

Заметьте, что это можно скомбинировать в единый вызов:
 

DBManager.EnumConnections(new
 

DBManager.EnumConnectionsCallback(ActiveConnectionsCallback));

 

 

 

 

 


11.01.2019; 17:03
хиты: 111
рейтинг:0
для добавления комментариев необходимо авторизироваться.
  Copyright © 2013-2024. All Rights Reserved. помощь