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

Страница 222 из 502

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

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

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

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

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

Еще в версии C# 2.0 было внедрено специальное средство, существенно упрощающее синтаксис присваивания метода делегату. Это так называемое групповое преобразование методов, позволяющее присвоить имя метода делегату, не прибегая к оператору new или явному вызову конструктора делегата.

Ниже приведен метод Main() из предыдущего примера, измененный с целью продемонстрировать групповое преобразование методов.

<b>static void Main() {</b>

<b>  // Сконструировать делегат, </b>

<b>  // используя групповое преобразование методов. </b>

<b>  StrMod strOp = 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 = RemoveSpaces; // использовать групповое преобразование методов </b>

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

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

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

<b>  strOp = Reverse; // использовать групповое преобразование методов </b>

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

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

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

<b>}</b>

Обратите особое внимание на то, как создается экземпляр делегата strOp и как ему присваивается метод ReplaсеSpaces в следующей строке кода.

<b>strOp = RemoveSpaces; // использовать групповое преобразование методов</b>

В этой строке кода имя метода присваивается непосредственно экземпляру делегата strOp, а все заботы по автоматическому преобразованию метода в тип делегата "возлагаются" на средства С#. Этот синтаксис может быть распространен на любую ситуацию, в которой метод присваивается или преобразуется в тип делегата.

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

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

<b>// Делегаты могут ссылаться и на методы экземпляра.</b>

<b>using System;</b>

<b>// Объявить тип делегата, </b>

<b>delegate string StrMod(string str);</b>

<b>class StringOps {</b>

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

<b>  public string ReplaceSpaces(string s) {</b>

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

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

<b>  }</b>

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

<b>  public string RemoveSpaces(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>    return temp;</b>

<b>  }</b>

<b>  // Обратить строку, </b>

<b>  public string Reverse(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>