Читать интересную книгу "Полное руководство. С# 4.0 - Шилдт Герберт"

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 101 102 103 104 105 106 107 108 109 ... 188

Как видите, count теперь явно объявлен как параметр типа int. Обратите такжевнимание на использование скобок. Теперь они необходимы. (Скобки могут быть опущены только в том случае, если задается лишь один параметр, а его тип явно не указывается.)

В предыдущем примере в обоих лямбда-выражениях использовался единственныйпараметр, но в целом у лямбда-выражений может быть любое количество параметров,в том числе и нулевое. Если в лямбда-выражении используется несколько параметров,их необходимо заключить в скобки. Ниже приведен пример использования лямбда-выражения с целью определить, находится ли значение в заданных пределах.(low, high, val) => val >= low && val <= high;

А вот как объявляется тип делегата, совместимого с этим лямбда-выражением.delegate bool InRange(int lower, int upper, int v);

Следовательно, экземпляр делегата InRange может быть создан следующим образом.InRange rangeOK = (low, high, val) => val >= low && val <= high;

После этого одиночное лямбда-выражение может быть выполнено так, как показано ниже.if(rangeOK(1, 5, 3)) Console.WriteLine( "Число 3 находится в пределах от 1 до 5.");

И последнее замечание: внешние переменные могут использоваться и захватываться в лямбда-выражениях таким же образом, как и в анонимных методах.Блочные лямбда-выражения

Как упоминалось выше, существуют две разновидности лямбда-выражений. Перваяиз них, одиночное лямбда-выражение, была рассмотрена в предыдущем разделе. Телотакого лямбда-выражения состоит только из одного выражения. Второй разновидностью является блочное лямбда-выражение. Для такого лямбда-выражения характернырасширенные возможности выполнения различных операций, поскольку в его теле допускается указывать несколько операторов. Например, в блочном лямбда-выраженииможно использовать циклы и условные операторы if, объявлять переменные и т.д.Создать блочное лямбда-выражение нетрудно. Для этого достаточно заключить теловыражения в фигурные скобки. Помимо возможности использовать несколько операторов, в остальном блочное лямбда-выражение, практически ничем не отличается оттолько что рассмотренного одиночного лямбда-выражения.

Ниже приведен пример использования блочного лямбда-выражения для вычисления и возврата факториала целого значения.// Продемонстрировать применение блочного лямбда-выражения.using System;// Делегат IntOp принимает один аргумент типа int// и возвращает результат типа int.delegate int IntOp(int end);class StatementLambdaDemo { static void Main() { // Блочное лямбда-выражение возвращает факториал // передаваемого ему значения. IntOp fact = n => { int r = 1; for(int i=1; i <= n; i++) 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();

1 ... 101 102 103 104 105 106 107 108 109 ... 188
Прочитали эту книгу? Оставьте комментарий - нам важно ваше мнение! Поделитесь впечатлениями и помогите другим читателям сделать выбор.
Книги, аналогичгные "Полное руководство. С# 4.0 - Шилдт Герберт"

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