В приведенном ниже примере программы демонстрируется применение двух оди ночных лямбда-выражений. Сначала в этой программе объявляются два типа делега тов. Первый из них, Incr, принимает аргумент типа int и возвращает результат того же типа. Второй делегат, IsEven, также принимает аргумент типа int, но возвращает результат типа bool. Затем экземплярам этих делегатов присваиваются одиночные лямбда-выражения. И наконец, лямбда-выражения вычисляются с помощью соответ ствующих экземпляров делегатов. // Применить два одиночных лямбда-выражения. using System; // Объявить делегат, принимающий аргумент типа int и // возвращающий результат типа int. delegate int Incr(int v); // Объявить делегат, принимающий аргумент типа int и // возвращающий результат типа bool. delegate bool IsEven(int v); class SimpleLambdaDemo { static void Main { // Создать делегат Incr, ссылающийся на лямбда-выражение. // увеличивающее свой параметр на 2. Incr incr = count => count + 2; // А теперь использовать лямбда-выражение incr. Console.WriteLine("Использование лямбда-выражения incr: "); int x = -10; while(x <= 0) { Console.Write(x + " "); x = incr(x); // увеличить значение x на 2 } Console.WriteLine ("\n"); // Создать экземпляр делегата IsEven, ссылающийся на лямбда-выражение, // возвращающее логическое значение true, если его параметр имеет четное // значение, а иначе — логическое значение false. IsEven isEven = n => n % 2 == 0; // А теперь использовать лямбда-выражение isEven. Console.WriteLine("Использование лямбда-выражения isEven: "); for(int i=l; i <= 10; i++) if(isEven(i)) Console.WriteLine(i + " четное."); } }
Вот к какому результату приводит выполнение этой программы. Использование лямбда-выражения incr: -10 -8 -6 -4 -2 0 Использование лямбда-выражения isEven: 2 четное. 4 четное. 6 четное. 8 четное. 10 четное.
Обратите в данной программе особое внимание на следующие строки объявлений. Incr incr = count => count + 2; IsEven isEven = n => n % 2 == 0;
В первой строке объявления экземпляру делегата incr присваивается одиночное лямбда-выражение, возвращающее результат увеличения на 2 значения параметра count. Это выражение может быть присвоено делегату Incr, поскольку оно совмести мо с объявлением данного делегата. Аргумент, указываемый при обращении к экзем пляру делегата incr, передается параметру count, который и возвращает результат вычисления лямбда-выражения. Во второй строке объявления делегату isEven при сваивается выражение, возвращающее логическое значение true, если передаваемый ему аргумент оказывается четным, а иначе — логическое значение false. Следователь но, это лямбда-выражение совместимо с объявлением делегата IsEven.
В связи со всем изложенным выше возникает резонный вопрос: каким обра зом компилятору становится известно о типе данных, используемых в лямбда- выражении, например, о типе int параметра count в лямбда-выражении, присваи ваемом экземпляру делегата incr? Ответить на этот вопрос можно так: компиля тор делает заключение о типе параметра и типе результата вычисления выражения по типу делегата. Следовательно, параметры и возвращаемое значение лямбда- выражения должны быть совместимы по типу с параметрами и возвращаемым зна чением делегата.
Несмотря на всю полезность логического заключения о типе данных, в некоторых случаях приходится явно указывать тип параметра лямбда-выражения. Для этого до статочно ввести конкретное название типа данных. В качестве примера ниже приведен другой способ объявления экземпляра делегата incr. Incr incr = (int count) => count + 2;
Как видите, 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.");