KnigaRead.com/
KnigaRead.com » Разная литература » Прочее » Герберт Шилдт - C# 4.0 полное руководство - 2011

Герберт Шилдт - C# 4.0 полное руководство - 2011

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн "Герберт Шилдт - C# 4.0 полное руководство - 2011". Жанр: Прочее издательство неизвестно, год неизвестен.
Перейти на страницу:

Анонимные функции

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

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

Анонимные методы

Анонимный метод — один из способов создания безымянного блока кода, связанного с конкретным экземпляром делегата. Для создания анонимного метода достаточно указать кодовый блок после ключевого слова delegate. Покажем, как это делается, на конкретном примере. В приведенной ниже программе анонимный метод служит для подсчета от 0 до 5.

// Продемонстрировать применение анонимного метода.

using System;

// Объявить тип делегата, delegate void Countlt();

class AnonMethDemo { static void Main() {

// Далее следует код для подсчета чисел, передаваемый делегату // в качестве анонимного метода.

Countlt count = delegate {

// Этот кодовый блок передается делегату, for (int i=0; i <= 5; i++)

Console.WriteLine(i) ;

}; // обратите внимание на точку с запятой

count();

}

}

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

0

1

2

3

4

5

Передача аргументов анонимному методу

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

// Продемонстрировать применение анонимного метода, принимающего аргумент, using System;

// Обратите внимание на то, что теперь у делегата Countlt имеется параметр, delegate void Countlt(int end);

class AnonMethDemo2 {

static void Main() {

// Здесь конечное значение для подсчета передается анонимному методу. Countlt count = delegate (int end) { for(int i=0; i <= end; i++)

Console.WriteLine(i);

};

count (3);

Console.WriteLine (); count (5);

}

}

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

0

1

2 3

0

1

2

3

4

5

Возврат значения из анонимного метода

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

// Продемонстрировать применение анонимного метода, возвращающего значение.

// Этот делегат возвращает значение, delegate int Countlt(int end);

class AnonMethDemo3 {

static void Main() { int result;

// Здесь конечное значение для подсчета передается анонимному методу. //А возвращается сумма подсчитанных чисел.

Countlt 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 применяется в анонимном методе таким же образом, как и в именованном методе. Ниже приведен результат выполнения данного кода.

0

1

2

3

Сумма 3 равна 6

0

1

2

3

4

5

Сумма 5 равна 15

Применение внешних переменных в анонимных методах

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

Захват локальной переменной может привести к неожиданным результатам. В качестве примера рассмотрим еще один вариант программы подсчета с суммированием чисел. В данном варианте объект Countlt конструируется и возвращается статическим методом Counter (). Этот объект использует переменную sum, объявленную в охватывающей области действия метода Counter (), а не самого анонимного метода. Поэтому переменная sum захватывается анонимным методом. Метод Counter () вызывается в методе Main () для получения объекта Countlt, а следовательно, переменная sum не уничтожается до самого конца программы.

// Продемонстрировать применение захваченной переменной, using System;

// Этот делегат возвращает значение типа int и принимает аргумент типа int. delegate int Countlt(int end);

class VarCapture {

static Countlt Counter ()    {

int sum = 0;

// Здесь подсчитанная сумма сохраняется в переменной sum.

Countlt ctObj = delegate (int end) { for(int i=0; i <= end; i++)    {

Console.WriteLine(i); sum += i;

}

return sum;

};

return ctObj;

}

static void Main() {

// Получить результат подсчета.

Countlt count = Counter ();

int result;

result = count(3);

Console.WriteLine("Сумма 3 равна " + result);

Console.WriteLine();

result = count(5);

Console.WriteLine("Сумма 5 равна " + result);

}

}

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

0

1

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*