Категории
Самые читаемые
onlinekniga.com » Компьютеры и Интернет » Программирование » Полное руководство. С# 4.0 - Шилдт Герберт

Полное руководство. С# 4.0 - Шилдт Герберт

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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 99 100 101 102 103 104 105 106 107 ... 188
Перейти на страницу:

В предыдущих примерах был наглядно продемонстрирован внутренний механизмдействия делегатов, но эти примеры не показывают их истинное назначение. Как правило, делегаты применяются по двум причинам. Во-первых, как упоминалось ранеев этой главе, делегаты поддерживают события. И во-вторых, делегаты позволяют вызывать методы во время выполнения программы, не зная о них ничего определенного в ходе компиляции. Это очень удобно для создания базовой конструкции, допускающей подключение отдельных программных компонентов. Рассмотрим в качествепримера графическую программу, аналогичную стандартной сервисной программеWindows Paint. С помощью делегата можно предоставить пользователю возможностьподключать специальные цветные фильтры или анализаторы изображений. Крометого, пользователь может составлять из этих фильтров или анализаторов целые последовательности. Подобные возможности программы нетрудно обеспечить, используя делегаты.Анонимные функции

Метод, на который ссылается делегат, нередко используется только для этой цели.Иными словами, единственным основанием для существования метода служит то обстоятельство, что он может быть вызван посредством делегата, но сам он не вызываетсявообще. В подобных случаях можно воспользоваться анонимной функцией, чтобы несоздавать отдельный метод. Анонимная функция, по существу, представляет собойбезымянный кодовый блок, передаваемый конструктору делегата. Преимущество анонимной функции состоит, в частности, в ее простоте. Благодаря ей отпадает необходимость объявлять отдельный метод, единственное назначение которого состоит в том,что он передается делегату.

Начиная с версии 3.0, в C# предусмотрены две разновидности анонимных функций: анонимные методы и лямбда-выражения. Анонимные методы были внедрены в C#еще в версии 2.0, а лямбда-выражения — в версии 3.0. В целом лямбда-выражение совершенствует принцип действия анонимного метода и в настоящее время считаетсяболее предпочтительным для создания анонимной функции. Но анонимные методышироко применяются в существующем коде С# и поэтому по-прежнему являютсяважной составной частью С#. А поскольку анонимные методы предшествовали появлению лямбда-выражений, то ясное представление о них позволяет лучше понятьособенности лямбда-выражений. К тому же анонимные методы могут быть использованы в целом ряде случаев, где применение лямбда-выражений оказывается невозможным. Именно поэтому в этой главе рассматриваются и анонимные методы, и лямбда-выражения.Анонимные методы

Анонимный метод — один из способов создания безымянного блока кода, связанного с конкретным экземпляром делегата. Для создания анонимного метода достаточно указать кодовый блок после ключевого слова delegate. Покажем, как это делается,на конкретном примере. В приведенной ниже программе анонимный метод служитдля подсчета от 0 до 5.// Продемонстрировать применение анонимного метода.using System;// Объявить тип делегата.delegate void CountIt();class AnonMethDemo { static void Main() { // Далее следует код для подсчета чисел, передаваемый делегату // в качестве анонимного метода. CountIt count = delegate { // Этот кодовый блок передается делегату. for(int i=0; i <= 5; i++) Console.WriteLine(i); }; // обратите внимание на точку с запятой count(); }}

В данной программе сначала объявляется тип делегата CountIt без параметрови с возвращаемым типом void. Далее в методе Main() создается экземпляр countделегата CountIt, которому передается кодовый блок, следующий после ключевогослова delegate. Именно этот кодовый блок и является анонимным методом, который будет выполняться при обращении к делегату count. Обратите внимание на то,что после кодового блока следует точка с запятой, фактически завершающая операторобъявления. Ниже приведен результат выполнения данной программы.012345Передача аргументов анонимному методу

Анонимному методу можно передать один или несколько аргументов. Для этогодостаточно указать в скобках список параметров после ключевого слова delegate,а при обращении к экземпляру делегата — передать ему соответствующие аргументы. В качестве примера ниже приведен вариант предыдущей программы, измененныйс целью передать в качестве аргумента конечное значение для подсчета.// Продемонстрировать применение анонимного метода, принимающего аргумент.using System;// Обратите внимание на то, что теперь у делегата CountIt имеется параметр.delegate void CountIt (int end);class AnonMethDemo2 { static void Main() { // Здесь конечное значение для подсчета передается анонимному методу. CountIt count = delegate (int end) { for(int i=0; i <= end; i++) Console.WriteLine(i); }; count(3); Console.WriteLine(); count(5); }}

В этом варианте программы делегат CountIt принимает целочисленный аргумент.Обратите внимание на то, что при создании анонимного метода список параметровуказывается после ключевого слова delegate. Параметр end становится доступнымдля кода в анонимном методе таким же образом, как и при создании именованногометода. Ниже приведен результат выполнения данной программы.0123012345Возврат значения из анонимного метода

Анонимный метод может возвращать значение. Для этой цели служит операторreturn, действующий в анонимном методе таким же образом, как и в именованномметоде. Как и следовало ожидать, тип возвращаемого значения должен быть совместим с возвращаемым типом, указываемым в объявлении делегата. В качестве примера ниже приведен код, выполняющий подсчет с суммированием и возвращающийрезультат.// Продемонстрировать применение анонимного метода, возвращающего значение.using System;// Этот делегат возвращает значение.delegate int CountIt(int end);class AnonMethDemo3 { static void Main() { int result; // Здесь конечное значение для подсчета перелается анонимному методу. // А возвращается сумма подсчитанных чисел. CountIt count = delegate (int end) { int sum = 0; for(int i=0; i <= end; i++) { Console.WriteLine (i); sum += i; } return sum; // возвратить значение из анонимного метода }; result = count(3); Console.WriteLine("Сумма 3 равна " + result); Console.WriteLine(); result = count (5); Console.WriteLine("Сумма 5 равна " + result); }}

В этом варианте кода суммарное значение возвращается кодовым блоком, связанным с экземпляром делегата count. Обратите внимание на то, что оператор returnприменяется в анонимном методе таким же образом, как и в именованном методе.Ниже приведен результат выполнения данного кода.0123Сумма 3 равна 6012345Сумма 5 равна 15Применение внешних переменных в анонимных методах

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

Захват локальной переменной может привести к неожиданным результатам. В качестве примера рассмотрим еще один вариант программы подсчета с суммированиемчисел. В данном варианте объект CountIt конструируется и возвращается статическимметодом Counter(). Этот объект использует переменную sum, объявленную в охватывающей области действия метода Counter(), а не самого анонимного метода. Поэтому переменная sum захватывается анонимным методом. Метод Counter() вызываетсяв методе Main() для получения объекта CountIt, а следовательно, переменная sum неуничтожается до самого конца программы.// Продемонстрировать применение захваченной переменной.using System;// Этот делегат возвращает значение типа int и принимает аргумент типа int.delegate int CountIt(int end);class VarCapture { static CountIt Counter() { int sum = 0; // Здесь подсчитанная сумма сохраняется в переменной sum. CountIt ctObj = delegate (int end) { for(int i=0; i <= end; i++) { Console.WriteLine(i); sum += i; } return sum; }; return ctObj; } static void Main() { // Получить результат подсчета. CountIt count = Counter(); int result; result = count(3); Console.WriteLine("Сумма 3 равна " + result); Console.WriteLine(); result = count (5); Console.WriteLine("Сумма 5 равна " + result); }}

1 ... 99 100 101 102 103 104 105 106 107 ... 188
Перейти на страницу:
На этой странице вы можете бесплатно читать книгу Полное руководство. С# 4.0 - Шилдт Герберт.
Комментарии