Добавить в цитаты Настройки чтения

Страница 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(&quot;Это простой тест.&quot;);</b>

<b>    Console.WriteLine(&quot;Результирующая строка: &quot; + str);</b>

<b>    Console.WriteLine();</b>

<b>    strOp = so.RemoveSpaces;</b>

<b>    str = strOp(&quot;Это простой тест.&quot;);</b>

<b>    Console.WriteLine(&quot;Результирующая строка: &quot; + str);</b>

<b>    Console.WriteLine();</b>

<b>    strOp = so.Reverse;</b>

<b>    str = strOp(&quot;Это простой тест.&quot;);</b>

<b>    Console.WriteLine(&quot;Результирующая строка: &quot; + 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(&quot;Замена пробелов дефисами.&quot;); </b>

<b>    s = s.Replace(' ' ,    '-');</b>

<b>  }</b>

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

<b>  static void RemoveSpaces(ref string s) {</b>

<b>    string temp = &quot;&quot;;</b>

<b>    int i;</b>

<b>    Console.WriteLine(&quot;Удаление пробелов.&quot;);</b>

<b>    for(i=0; i &lt; 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 = &quot;&quot;;</b>

<b>    int i, j;</b>

<b>    Console.WriteLine(&quot;Обращение строки.&quot;);</b>

<b>    for(j=0, i=s.Length-1; i &gt;= 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 = &quot;Это простой тест.&quot;;</b>

<b>    // Организовать групповую адресацию.</b>

<b>    strOp = replaceSp;</b>

<b>    strOp += reverseStr;</b>

<b>    // Обратиться к делегату с групповой адресацией. </b>

<b>    strOp(ref str);</b>

<b>    Console.WriteLine(&quot;Результирующая строка: &quot; + str);</b>