Чтение онлайн

ЖАНРЫ

C# 4.0 полное руководство - 2011

Шилдт Герберт

Шрифт:

Тип делегата объявляется с помощью ключевого слова delegate. Ниже приведена общая форма объявления делегата:

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

где возвращаемый_тип обозначает тип значения, возвращаемого методами, которые будут вызываться делегатом; имя — конкретное имя делегата; список_параметров — параметры, необходимые

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

Самое главное, что делегат может служить для вызова любого метода с соответствующей сигнатурой и возвращаемым типом. Более того, вызываемый метод может быть методом экземпляра, связанным с отдельным объектом, или же статическим методом, связанным с конкретным классом. Значение имеет лишь одно: возвращаемый тип и сигнатура метода должны быть согласованы с теми, которые указаны в объявлении делегата.

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

// Простой пример применения делегата.

using System;

// Объявить тип делегата, delegate string StrMod(string str);

class DelegateTest {

// Заменить пробелы дефисами.

static string ReplaceSpaces(string s) {

Console.WriteLine("Замена пробелов дефисами."); return s.Replace(' ', '-');

}

// Удалить пробелы.

static string RemoveSpaces(string s) { string temp = ""; int i;

Console.WriteLine("Удаление пробелов."); for(i=0; i < s.Length; i++) if(s[i] != ' ') temp += s[i];

return temp;

}

// Обратить^строку. static string Reverse(string s) { string temp = ""; int i, j;

Console.WriteLine("Обращение строки. ") ; for(j=0, i=s.Length-1; i >= 0; i—, j++) temp += s[i];

return temp;

}

static void Main {

// Сконструировать делегат.

StrMod strOp = new StrMod(ReplaceSpaces) ; string str;

// Вызвать методы с помощью делегата, str = strOp("Это простой тест.");

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, как показано ниже.

delegate string StrMod(string str);

Как видите, делегат StrMod принимает один параметр типа string и возвращает одно значение того же типа.

Далее в классе DelegateTest объявляются три статических метода с одним параметром типа string и возвращаемым значением того же типа. Следовательно, они соответствуют делегату StrMod. Эти методы видоизменяют строку в той или иной форме. Обратите внимание на то, что в методе Rep la се Spaces для замены пробелов дефисами используется один из методов типа string — Replace .

В методе Main создается переменная экземпляра strOp ссылочного типа StrMod и затем ей присваивается ссылка на метод ReplaceSpaces . Обратите особое внимание на следующую строку кода.

StrMod strOp = new StrMod(ReplaceSpaces);

В этой строке метод ReplaceSpaces передается в качестве параметра. При этом указывается только его имя, но не параметры. Данный пример можно обобщить: при получении экземпляра делегата достаточно указать только имя метода, на который должен ссылаться делегат. Ясно, что сигнатура метода должна совпадать с той, что указана в объявлении делегата. В противном случае во время компиляции возникнет ошибка.

Далее метод ReplaceSpaces вызывается с помощью экземпляра делегата strOp, как показано ниже.

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

Экземпляр делегата strOp ссылается на метод ReplaceSpaces , и поэтому вызывается именно этот метод.

Затем экземпляру делегата strOp присваивается ссылка на метод RemoveSpaces , и с его помощью вновь вызывается указанный метод — на этот раз RemoveSpaces .

И наконец, экземпляру делегата strOp присваивается ссылка на метод Reverse . А в итоге вызывается именно этот метод.

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

Поделиться с друзьями: