Рейтинговые книги
Читем онлайн C# 4.0: полное руководство - Герберт Шилдт

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 128 129 130 131 132 133 134 135 136 ... 294

        r = i * r;

      return r;

    };

    Console.WriteLine("Факториал 3 равен " + fact(3));

    Console.WriteLine("Факториал 5 равен " + fact(5));

  }

}

При выполнении этого кода получается следующий результат.

Факториал 3 равен 6

Факториал 5 равен 120

В приведенном выше примере обратите внимание на то, что в теле блочного лямбда-выражения объявляется переменная r, организуется цикл for и используется оператор return. Все эти элементы вполне допустимы в блочном лямбда-выражении. И в этом отношении оно очень похоже на анонимный метод. Следовательно, многие анонимные методы могут быть преобразованы в блочные лямбда-выражения при обновлении унаследованного кода. И еще одно замечание: когда в блочном лямбда-выражении встречается оператор return, он просто обусловливает возврат из лямбда-выражения, но не возврат из охватывающего метода.

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

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

// целью использовать блочные лямбда-выражения.

using System;

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

delegate string StrMod(string s);

class UseStatementLambdas {

  static void Main() {

    // Создать делегаты, ссылающиеся на лямбда- выражения,

    // выполняющие различные операции с символьными строками.

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

    StrMod ReplaceSpaces = s => {

      Console.WriteLine("Замена пробелов дефисами.");

      return s.Replace(' ', '-');

    };

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

    StrMod RemoveSpaces = s => {

      string temp = "";

      int i;

      Console.WriteLine("Удаление пробелов.");

      for(i=0; i < s.Length; i++)

        if(s[i] != ' ') temp += s[i];

      return temp;

    };

    // Обратить строку.

    StrMod Reverse = s => {

      string temp = ""; int i, j;

      Console.WriteLine("Обращение строки.");

      for(j=0, i=s.Length-1; i >= 0; i--, j++) temp += s[i];

      return temp;

    };

    string str;

    // Обратиться к лямбда-выражениям с помощью делегатов.

    StrMod strOp = ReplaceSpaces;

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

    Console.WriteLine("Результирующая строка: " + str);

    Console.WriteLine() ;

    strOp = RemoveSpaces;

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

    Console.WriteLine("Результирующая строка: " + str);

    Console.WriteLine();

    strOp = Reverse;

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

    Console.WriteLine("Результирующая строка: " + str);

  }

}

Результат выполнения кода этого примера оказывается таким же, как и в первом примере применения делегатов.

Замена пробелов дефисами.

Результирующая строка: Это-простой-тест.

Удаление пробелов.

Результирующая строка: Этопростойтест.

Обращение строки.

Результирующая строка: .тсет йотсорп отЭ

События

Еще одним важным средством С#, основывающимся на делегатах, является событие. Событие, по существу, представляет собой автоматическое уведомление о том, что произошло некоторое действие. События действуют по следующему принципу: объект, проявляющий интерес к событию, регистрирует обработчик этого события. Когда же событие происходит, вызываются все зарегистрированные обработчики этого события. Обработчики событий обычно представлены делегатами.

События являются членами класса и объявляются с помощью ключевого слова event. Чаще всего для этой цели используется следующая форма:

event делегат_события имя_события;

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

Рассмотрим для начала очень простой пример.

// Очень простой пример, демонстрирующий событие,

using System;

// Объявить тип делегата для события,

delegate void MyEventHandler();

// Объявить класс, содержащий событие,

class MyEvent {

  public event MyEventHandler SomeEvent;

  // Этот метод вызывается для запуска события,

  public void OnSomeEvent() {

    if (SomeEvent != null)

    SomeEvent();

  }

}

class EventDemo {

// Обработчик события,

  static void Handler() {

    Console.WriteLine("Произошло событие");

  }

  static void Main() {

    MyEvent evt = new MyEvent();

    // Добавить метод Handler() в список событий,

    evt.SomeEvent += Handler;

    // Запустить событие,

    evt.OnSomeEvent();

  }

}

Вот какой результат получается при выполнении этого кода.

Произошло событие

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

delegate void MyEventHandler();

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

Далее создается класс события MyEvent. В этом классе объявляется событие SomeEvent в следующей строке кода.

public event MyEventHandler SomeEvent;

Обратите внимание на синтаксис этого объявления. Ключевое слово event уведомляет компилятор о том, что объявляется событие.

Кроме того, в классе MyEvent объявляется метод OnSomeEvent(), вызываемый для сигнализации о запуске события. Это означает, что он вызывается, когда происходит событие. В методе OnSomeEvent() вызывается обработчик событий с помощью делегата SomeEvent.

if(SomeEvent != null)

  SomeEvent();

Как видите, обработчик вызывается лишь в том случае, если событие SomeEvent не является пустым. А поскольку интерес к событию должен быть зарегистрирован в других частях программы, чтобы получать уведомления о нем, то метод OnSomeEvent() может быть вызван до регистрации любого обработчика события. Но во избежание вызова по пустой ссылке делегат события должен быть проверен, чтобы убедиться в том, что он не является пустым.

В классе EventDemo создается обработчик событий Handler(). В данном простом примере обработчик событий просто выводит сообщение, но другие обработчики могут выполнять более содержательные функции. Далее в методе Main() создается объект класса события MyEvent, a Handler() регистрируется как обработчик этого события, добавляемый в список.

MyEvent evt = new MyEvent();

// Добавить метод Handler() в список событий,

evt.SomeEvent += Handler;

Обратите внимание на то, что обработчик добавляется в список с помощью оператора +=. События поддерживают только операторы += и -=. В данном случае метод Handler() является статическим, но в качестве обработчиков событий могут также служить методы экземпляра.

1 ... 128 129 130 131 132 133 134 135 136 ... 294
На этой странице вы можете бесплатно читать книгу C# 4.0: полное руководство - Герберт Шилдт бесплатно.
Похожие на C# 4.0: полное руководство - Герберт Шилдт книги

Оставить комментарий