Страница 223 из 502
<b> return temp;</b>
<b> }</b>
<b>}</b>
<b>class DelegateTest {</b>
<b> static void Main() {</b>
<b> StringOps so = new StringOps(); // создать экземпляр</b>
<b> // объекта класса StringOps</b>
<b> // Инициализировать делегат.</b>
<b> StrMod strOp = so.ReplaceSpaces;</b>
<b> string str;</b>
<b> // Вызвать методы с помощью делегатов,</b>
<b> str = strOp("Это простой тест.");</b>
<b> Console.WriteLine("Результирующая строка: " + str);</b>
<b> Console.WriteLine();</b>
<b> strOp = so.RemoveSpaces;</b>
<b> str = strOp("Это простой тест.");</b>
<b> Console.WriteLine("Результирующая строка: " + str);</b>
<b> Console.WriteLine();</b>
<b> strOp = so.Reverse;</b>
<b> str = strOp("Это простой тест.");</b>
<b> Console.WriteLine("Результирующая строка: " + str);</b>
<b> }</b>
<b>}</b>
Результат выполнения этого кода получается таким же, как и в предыдущем примере, но на этот раз делегат обращается к методам по ссылке на экземпляр объекта класса StringOps.
Одним из самых примечательных свойств делегата является поддержка групповой адресации. Попросту говоря, групповая адресация — это возможность создать список, или цепочку вызовов, для методов, которые вызываются автоматически при обращении к делегату. Создать такую цепочку нетрудно. Для этого достаточно получить экземпляр делегата, а затем добавить методы в цепочку с помощью оператора + или +=. Для удаления метода из цепочки служит оператор - или -=. Если делегат возвращает значение, то им становится значение, возвращаемое последним методом в списке вызовов. Поэтому делегат, в котором используется групповая адресация, обычно имеет возвращаемый тип void.
Ниже приведен пример групповой адресации. Это переработанный вариант предыдущих примеров, в котором тип значений, возвращаемых методами манипулирования строками, изменен на void, а для возврата измененной строки в вызывающую часть кода служит параметр типа ref. Благодаря этому методы оказываются более приспособленными для групповой адресации.
<b>// Продемонстрировать групповую адресацию.</b>
<b>using System;</b>
<b>// Объявить тип делегата.</b>
<b>delegate void StrMod(ref string str);</b>
<b>class MultiCastDemo {</b>
<b> // Заменить пробелы дефисами.</b>
<b> static void ReplaceSpaces(ref string s) {</b>
<b> Console.WriteLine("Замена пробелов дефисами."); </b>
<b> s = s.Replace(' ' , '-');</b>
<b> }</b>
<b> // Удалить пробелы.</b>
<b> static void RemoveSpaces(ref string s) {</b>
<b> string temp = "";</b>
<b> int i;</b>
<b> Console.WriteLine("Удаление пробелов.");</b>
<b> for(i=0; i < s.Length; i++)</b>
<b> if(s[i] != ' ') temp += s[i];</b>
<b> s = temp;</b>
<b> }</b>
<b> // Обратить строку.</b>
<b> static void Reverse(ref string s) {</b>
<b> string temp = "";</b>
<b> int i, j;</b>
<b> Console.WriteLine("Обращение строки.");</b>
<b> for(j=0, i=s.Length-1; i >= 0; i—, j++) temp += s[i];</b>
<b> s = temp;</b>
<b> }</b>
<b> static void Main() {</b>
<b> // Сконструировать делегаты.</b>
<b> StrMod strOp;</b>
<b> StrMod replaceSp = ReplaceSpaces;</b>
<b> StrMod removeSp = RemoveSpaces;</b>
<b> StrMod reverseStr = Reverse;</b>
<b> string str = "Это простой тест.";</b>
<b> // Организовать групповую адресацию.</b>
<b> strOp = replaceSp;</b>
<b> strOp += reverseStr;</b>
<b> // Обратиться к делегату с групповой адресацией. </b>
<b> strOp(ref str);</b>
<b> Console.WriteLine("Результирующая строка: " + str);</b>