Рассмотрим пример определения и применения делегата. В этом примере у нас есть класс менеджера базы данных, который отслеживает все активные соединения с БД и предоставляет метод перечисления этих соединений. Если допустить, что менеджер БД находится на удаленной машине, правильным решением будет сделать метод асинхронным, позволив клиенту предоставлять метод обратного вызова. Заметьте: в реальном приложении вам следовало бы задействовать многопоточность, чтобы добиться подлинной асинхронности. Но для упрощения примера и поскольку мы не рассматривали многопоточность, пока не будем ее применять.
Для начала определим два главных класса:
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));
Вот и все, что касается базового синтаксиса делегатов. Теперь посмотрим на законченный пример:
using System;
class DBConnection {
public DBConnection(string name) {
this.name = name; }
protected string Name; public string name {
get {
return this.Маше; }
set {
this.Name = value; > } }
class DBManager {
static DBConnection[] activeConnections;
public void AddConnectionsO
{
activeConnections = new DBConnection[5];
for (int i = 0; i < 5; i++)
{
activeConnections[i] = new DBConnection("DBConnection " + (i + 1)); > }
public delegate void EnumConnectionsCallback(DBConnection
connection); public static void EnumConnections(EnumConnectionsCallback
callback) {
foreach (DBConnection connection in activeConnections)
{
callback(connection);
} } >
class DelegatelApp {
public static void ActiveConnectionsCallback(DBConnection
connection) <
Console.WriteLine("Callback method called for "
+ connection.name); }
public static void Main() {
DBManager dbMgr = new DBManagerO; dbMg r.AddConnections();
DBManager.EnumConnectionsCallback myCallback = new DBManager.EnumConnectionsCallback (ActiveConnectionsCallback);
DBManager.EnumConnections(myCallback); } }
После компиляции и запуска этого приложения мы получим такие результаты:
Callback method called for DBConnection 1 Callback method called for DBConnection 2 Callback method called for DBConnection 3 Callback method called for DBConnection 4 Callback method called for DBConnection 5