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 применяется в анонимном методе таким же образом, как и в именованном методе. Ниже приведен результат выполнения данного кода.
0
1
2
3
Сумма 3 равна 6
0
1
2
3
4
5
Сумма 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);
}
}
Ниже приведен результат выполнения этой программы. Обратите особое внимание на суммарное значение.
0
1
2
3
Сумма 3 равна 6
0
1
2
3
4
5
Сумма 5 равна 21
Как видите, подсчет по-прежнему выполняется как обычно. Но обратите внимание на то, что сумма 5 теперь равна 21, а не 15! Дело в том, что переменная sum захватывается объектом ctObj
при его создании в методе Counter()
. Это означает, что она продолжает существовать вплоть до уничтожения делегата count
при "сборке мусора" в самом конце программы. Следовательно, ее значение не уничтожается после возврата из метода Counter()
или при каждом вызове анонимного метода, когда происходит обращение к делегату count в методе Main()
.