Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
8
Добавлен:
21.05.2015
Размер:
7.55 Кб
Скачать

Делегат — это объект, который может ссылаться на метод. Создавая делегат, по сути, создаёте объект, который может содержать ссылку на метод. Более того, этот метод можно вызватьпосредством соответствующей ссылки. Таким образом, делегат может вызывать метод,на который он ссылается.

Ссылка по существупредставляет собой адрес памяти. Следовательно, ссылка на объект — это адрес объекта. Даже несмотря на то, что метод не является объектом, он тоже имеет отношениек физической области памяти, а адрес его точки входа — это адрес, к которому происходит обращение при вызове метода. Этот адрес можно присвоить делегату. Если ужделегат ссылается на метод, этот метод можно вызвать посредством данного делегата.

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

Делегат объявляется с помощью ключевого слова delegate. Общая форма объявления делегата имеет следующий вид:

delegate тип_возврата имя(список_параметров);

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

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

using System;

// Объявляем делегат.

delegate string strMod(string str);

classDelegateTest {

// Метод заменяет пробелы дефисами

static string replaceSpaces(string a) {

Console.WriteLine("Замена пробелов дефисами.");

return a.Replace(' ', ' - ' ) ;

}

static string removeSpaces(string a) {// Метод удаляет пробелы.

string temp = "";

int i;

Console.WriteLine("Удаление пробелов.");

for(i=0; i < a.Length; i++)

if (a[i] != ' f) temp += a[i] ;

return temp;

}

static string reverse(string a) {// Метод реверсирует строку,

string temp = "";

int i, j;

Console.WriteLine("Реверсирование строки.");

for(j=0, i=a.Length-1; i >= 0; i--, j++)

temp += a[i];

return temp;

}

public static void Main() {

strMod strOp = new strMod(replaceSpaces); // Создание делегата.

string str;

// Вызываем методы посредством делегата.

str = str0p("ЭTO простой тест.");

Console.WriteLine("Результирующая строка: " + str);

Console.WriteLine();

strOp = new strMod(removeSpaces);

str = strOp("Это простой тест.");

Console.WriteLine("Результирующая строка: " + str);

Console.WriteLine();

strOp = new strMod(reverse);

str = strOp("Это простой тест.");

Console.WriteLine("Результирующая строка: " + str);

}}

Результаты выполнения этой программы выглядят так:

Замена пробелов дефисами.

Результирующая строка: Это-простой-тест.

Удаление пробелов.

Результирующая строка: Этопростойтест.

Реверсирование строки.

Результирующая строка: .тсет йотсорп отЭ

В программе объявляется делегат с именем strMod, который принимаетодин параметр типа string и возвращает string-значение. В классе DelegateTestобъявлены три статических метода, сигнатура которых совпадает с сигнатурой, заданной делегатом. Эти методы предназначены для модификации строк определенноговида. Обратите внимание на то, что метод replaceSpaces () для замены пробеловдефисами использует метод Replace () — один из методов класса string.

В методе Main () создается ссылка типа strMod с именем strOp, и ей присваивается ссылка на метод replaceSpaces(). Внимательно рассмотрите следующую строку:

strMod strOp = new strMod(replaceSpaces);

Обратите внимание на то, что метод replaceSpaces() передается делегату в качестве параметра. Здесь используется только имя метода (параметры не указываются).Это наблюдение можно обобщить: при реализации делегата задается только имя метода, на который должен ссылаться этот делегат.Кроме того, объявление метода должно соответствовать объявлению делегата. В противном случае вы получите сообщение обошибке еще во время компиляции.

Затем метод replaceSpaces() вызывается посредством экземпляра делегата сименем strOp, как показано в следующей строке:

str = strOp("Это простой т е с т . " ) ;

Поскольку экземпляр strOp ссылается на метод replaceSpaces(), то вызываетсяименно метод replaceSpaces(). Затем экземпляру делегата strOp присваиваетсяссылка на метод removeSpaces(), после чего strOp вызывается снова. На этот развызывается метод removeSpaces ().

Наконец, экземпляру делегата strOp присваивается ссылка на метод reverse(), иstrOp вызывается еще раз. Это, как нетрудно догадаться, приводит к вызову метода reverse().

Главное в этом примере то, что вызов экземпляра делегата strOp трансформируется в обращение к методу, на который ссылается strOp при вызове. Таким образом, решение о вызываемом методе принимается во время выполнения программы, а не впериод компиляции.