Для того чтобы показать делегат в действии, рассмотрим для начала простой при мер его применения. // Простой пример применения делегата. 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. Эти методы видоизменяют строку в той или иной фор ме. Обратите внимание на то, что в методе ReplaceSpaces для замены пробелов дефисами используется один из методов типа string — Replace.
В методе Main создается переменная экземпляра strOp ссылочного типа StrMod и затем ей присваивается ссылка на метод ReplaceSpaces. Обратите особое внима ние на следующую строку кода. StrMod strOp = new StrMod(ReplaceSpaces);
В этой строке метод ReplaceSpaces передается в качестве параметра. При этом указывается только его имя, но не параметры. Данный пример можно обобщить: при получении экземпляра делегата достаточно указать только имя метода, на который должен ссылаться делегат. Ясно, что сигнатура метода должна совпадать с той, что указана в объявлении делегата. В противном случае во время компиляции возникнет ошибка.
Далее метод ReplaceSpaces вызывается с помощью экземпляра делегата strOp, как показано ниже. str = strOp("Это простой тест.");
Экземпляр делегата strOp ссылается на метод ReplaceSpaces, и поэтому вы зывается именно этот метод.
Затем экземпляру делегата strOp присваивается ссылка на метод RemoveSpaces, и с его помощью вновь вызывается указанный метод — на этот раз RemoveSpaces. И наконец, экземпляру делегата strOp присваивается ссылка на метод Reverse. А в итоге вызывается именно этот метод.
Главный вывод из данного примера заключается в следующем: в тот момент, когда происходит обращение к экземпляру делегата strOp, вызывается метод, на который он ссылается. Следовательно, вызов метода разрешается во время выполнения, а не в процессе компиляции. Групповое преобразование делегируемых методов
Еще в версии C# 2.0 было внедрено специальное средство, существенно упрощаю щее синтаксис присваивания метода делегату. Это так называемое групповое преобразо вание методов, позволяющее присвоить имя метода делегату, не прибегая к оператору new или явному вызову конструктора делегата.