Страница 229 из 502
<b> }</b>
<b> Console.WriteLine ("n");</b>
<b> // Создать экземпляр делегата IsEven, ссылающийся на лямбда-выражение,</b>
<b> // возвращающее логическое значение true, если его параметр имеет четное</b>
<b> // значение, а иначе — логическое значение false.</b>
<b> IsEven isEven = n => n % 2 == 0;</b>
<b> // А теперь использовать лямбда-выражение isEven.</b>
<b> Console.WriteLine("Использование лямбда-выражения isEven: ");</b>
<b> for (int i=1; i <= 10; i++)</b>
<b> if(isEven (i)) Console.WriteLine(i + " четное.");</b>
<b> }</b>
<b>}</b>
Вот к какому результату приводит выполнение этой программы.
<b>Использование лямбда-выражения incr:</b>
<b>-10 -8 -6 -4 -2 0</b>
<b>Использование лямбда-выражения isEven:</b>
<b>2 четное.</b>
<b>4 четное.</b>
<b>6 четное.</b>
<b>8 четное.</b>
<b>10 четное.</b>
Обратите в данной программе особое внимание на следующие строки объявлений.
<b>Incr incr = count => count +2;</b>
<b>IsEven isEven = n => n % 2 == 0;</b>
В первой строке объявления экземпляру делегата incr присваивается одиночное лямбда-выражение, возвращающее результат увеличения на 2 значения параметра count. Это выражение может быть присвоено делегату Incr, поскольку оно совместимо с объявлением данного делегата. Аргумент, указываемый при обращении к экземпляру делегата incr, передается параметру count, который и возвращает результат вычисления лямбда-выражения. Во второй строке объявления делегату isEven присваивается выражение, возвращающее логическое значение true, если передаваемый ему аргумент оказывается четным, а иначе — логическое значение false. Следовательно, это лямбда-выражение совместимо с объявлением делегата IsEven.
В связи со всем изложенным выше возникает резонный вопрос: каким образом компилятору становится известно о типе данных, используемых в лямбда-выражении, например, о типе int параметра count в лямбда-выражении, присваиваемом экземпляру делегата incr? Ответить на этот вопрос можно так: компилятор делает заключение о типе параметра и типе результата вычисления выражения по типу делегата. Следовательно, параметры и возвращаемое значение лямбда-выражения должны быть совместимы по типу с параметрами и возвращаемым значением делегата.
Несмотря на всю полезность логического заключения о типе данных, в некоторых случаях приходится явно указывать тип параметра лямбда-выражения. Для этого достаточно ввести конкретное название типа данных. В качестве примера ниже приведен другой способ объявления экземпляра делегата incr.
<b>Incr incr = (int count) => count + 2;</b>
Как видите, count теперь явно объявлен как параметр типа int. Обратите также внимание на использование скобок. Теперь они необходимы. (Скобки могут быть опущены только в том случае, если задается лишь один параметр, а его тип явно не указывается.)
В предыдущем примере в обоих лямбда-выражениях использовался единственный параметр, но в целом у лямбда-выражений может быть любое количество параметров, в том числе и нулевое. Если в лямбда-выражении используется несколько параметров, их необходимо заключить в скобки. Ниже приведен пример использования лямбда-выражения с целью определить, находится ли значение в заданных пределах.
<b>(low, high, val) => val >= low && val <= high;</b>
А вот как объявляется тип делегата, совместимого с этим лямбда-выражением.
<b>delegate bool InRange(int lower, int upper, int v);</b>
Следовательно, экземпляр делегата InRange может быть создан следующим образом.
<b>InRange rangeOK = (low, high, val) => val >= low && val <= high;</b>
После этого одиночное лямбда-выражение может быть выполнено так, как показано ниже.
<b>if(rangeOK(1, 5, 3)) Console.WriteLine(</b>
<b> "Число 3 находится в пределах от 1 до 5.");</b>
И последнее замечание: внешние переменные могут использоваться и захватываться в лямбда-выражениях таким же образом, как и в анонимных методах.
Как упоминалось выше, существуют две разновидности лямбда-выражений. Первая из них, одиночное лямбда-выражение, была рассмотрена в предыдущем разделе. Тело такого лямбда-выражения состоит только из одного выражения. Второй разновидностью является блочное лямбда-выражение. Для такого лямбда-выражения характерны расширенные возможности выполнения различных операций, поскольку в его теле допускается указывать несколько операторов. Например, в блочном лямбда-выражении можно использовать циклы и условные операторы if, объявлять переменные и т.д. Создать блочное лямбда-выражение нетрудно. Для этого достаточно заключить тело выражения в фигурные скобки. Помимо возможности использовать несколько операторов, в остальном блочное лямбда-выражение, практически ничем не отличается от только что рассмотренного одиночного лямбда-выражения.
Ниже приведен пример использования блочного лямбда-выражения для вычисления и возврата факториала целого значения.