1. Анонимные методы.
Анонимные методы появились еще в версии C# 2.0. Применяют их и сегодня. Хоть и на смену анонимным методам в версии С# 3.0 пришли лямбда выражения, все же со счетов их списывать не стоит. Само название говорит, что метод анонимный, то есть не имеет названия! Лямбда выражения будет легче понять после рассмотрения анонимных методов. Анонимный метод – один из способов создать безымянный блок, который будет связан с конкретным делегатом.
delegate void Anonim(); // сигнатура делегата
Создадим анонимный метод, который выведет нам на консоль все директории указанного каталога на компьютере:
// используем анонимный метод
Anonim anonim = delegate{
DirectoryInfo dir = new DirectoryInfo("D:\\");
foreach (DirectoryInfo d in dir.GetDirectories())
Console.WriteLine(d.Name);
};
anonim(); // запускаем

Видим, что блок безымянный. Просто конкретному делегату мы указали данный блок.
А теперь рассмотрим пример использования анонимных методов с параметрами. Для этого определим делегат:
// сигнатура делегата
delegate void Anonim2(int start, int finish);
// теперь аноним. метод с параметрами
Anonim2 anonim2 = delegate(int a, int b) {
for (int i = a; i <= b; i++)
Console.Write("Бегун сейчас на {0} километре." +
" До финиша осталось {1}\n", i, b-i);
};
anonim2(1, 10);

После слова delegate, в скобках указываются параметры, вот и вся комедия. Можно использовать еще анонимные методы, которые возвращают значения. Для этого просто измените в сигнатуре делегата тип void на другой тип, к примеру – int, а в методе используйте слово return для возврата значения из метода.
2. Лямбда выражения.
Лямбда выражения, это более лучшая замена анонимным методам, которая основываются на новом синтаксисе. Во всех лямбда выражениях должен быть лямбда оператор “=>”. Этот оператор разделяет выражение на две части.
- В левой части – параметры (может быть несколько);
- В правой части – тело метода;
Есть еще такие понятия, как одиночные
и блочные лямбда выражения. Все просто, если у нас после цикла for или оператора
if включается одна строчка кода,
то незачем включать эту строку в фигурные скобки. Это относится к одиночным лямбда выражениям, но если в выражение несколько строчек, нужно захватить этот блок в фигурные скобки.
Я бы распределил использование лямбда выражения на три этапа:
- Определения делегата, совместимого с лямбда-выражением.
- Создание экземпляра делегата, которому присваивается лямбда-выражение.
- Этот этап, уже само использование выражение, которое происходит при обращение к делегату.
Одиночные лямбда-выражения:
Этап 1:
delegate int Pow(int change);
Этап 2:
Pow pow = change => change * change;
Этап 3:
Console.WriteLine(pow(10)); // ризультат будет 100
Теперь перепишем пример про бегуна с использованием лямбда-выражения.
// сигнатура делегата
// совместимого с лямбда-выражением.
delegate int LambdaDelegate(int step);
LambdaDelegate lambdaDel = a => ++a;
int step = 1;
int finish = 10;
while (step <= finish)
{
Console.Write("Бегун сейчас на {0} километре." +
" До финиша осталось {1}\n", step, finish - step);
step = lambdaDel(step);
}
Результат будет тот же, что при использование анонимных методов. Типы параметров не указываются. Компилятор сам определяет, какие типы имеют параметры, исходя из делегата и его типа, который возвращается. Хотя, можно и явно
указать тип, к примеру так:
LambdaDelegate lambdaDel = (int a) => ++a;
Обратите внимание на выражение “++a”. Об этом нюансе говорилось в курсе по C# первой части. Если переписать, к примеру, вот так: “a++” – будет бесконечный цикл!
Блочные лямбда-выражения:
Чтоб создать блочное лямбда-выражение, нужно просто его взять в фигурные скобки. Преимущества в использование блочных выражений проявляется в том, что есть возможность управлять такими операторами как if,
for и т.д. Все также как при написание простых методов.
Этап 1:
delegate int Pow(int change);
Этап 2:
Pow lambdaDel = change =>
{
if (change != 0)
return change * change;
return 0;
};
Этап 3:
Console.WriteLine(pow(10)); // ризультат будет 100