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

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

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

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

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

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

В программе объявляется делегат с именем 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 при вызове. Таким образом, решение о вызываемом методе принимается во время выполнения программы, а не впериод компиляции.

 

8.2 Многоадресатная передача

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

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

Делегат с многоадресатной передачей имеет одно ограничение: он должен возвращать тип void.

Рассмотрим следующий пример многоадресатной передачи. Это — переработанный вариант предыдущих примеров, в котором тип string для значений, возвращаемых методами обработки строк, заменен типом void, а для возврата модифицированных строк используется ref-параметр.

 

using System;

delegate void strMod(ref string str); // Объявляем делегат.

class StringOps {

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

static void replaceSpaces(ref string a) {

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

a = a.Replace(‘‘,’–‘ ) ;

}

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

string temp = "";

int i;

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

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

if(a[i] != ‘ ’) temp += a[i];

a = temp;

}

// Метод реверсирует строку,

static void reverse(ref string a) {

string temp = "";

int i, j;

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

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

temp += a[i];

a = temp;

}

public static void Main() {

// Создаем экземпляры делегатов.

strMod strOp;

strMod replaceSp = new strMod(replaceSpaces);

strMod removeSp = new strMod(removeSpaces);

strMod reverseStr = new strMod(reverse);

string str = "Это простой тест.";

// Организация многоадресатной передачи.

strOp = replaceSp;

strOp += reverseStr;

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

strOp(ref str);

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

Console.WriteLine();

// Удаляем метод замены пробелов и

// добавляем метод их удаления.

strOp -= replaceSp;

strOp += removeSp;

str = "Это простой тест."; // Восстановление

// исходной строки.

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

strOp(ref str);

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

Console.WriteLine();

}}

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