Программирование >>  Программирование с использованием ajax 

1 ... 132 133 134 [ 135 ] 136 137 138 ... 396


В методе Main () создаются три лямбда-выражения, которые затем по очереди используются для вызова метода PerformOperations (). Первый из этих вызовов выглядит следующим образом:

Console.WriteLine( f(а, b) = а + b: );

PerformOperations((paramA, paramB) => paramA + paramB); Лямбда-выражением здесь является: (paramA, paramB) => paramA + paramB Опять-таки, oho делится на три описанных ниже части.

1. Раздел определения параметров. Здесь определены два параметра - paramA и paramB. Они являются не типизированными, а это значит, что компилятор может выводить типы этих параметров из контекста. В данном случае он может определить, что вызов метода PerformOperations () требует использования делегата типа TwoIntegerOperationDelegate. У этого типа делегата имеется два параметра int, так что путем выведения получается, что типом и paramA, и paramB является int.

2. Операция =>. Она просто отделяет параметры от тела лямбда-выражения.

3. Тело выражения. Здесь задается простая операция, подразумевающая суммирование параметров paramA и paramB. Обратите внимание на то, что указывать, что это является возвращаемым значением, нет никакой необходимости. Компилятору известно о том, что для создания метода, пригодного для использования TwoIntegerOperationDelegate, необходимо, чтобы его возвращаемым типом был int. Поскольку заданная операция - paramA+paramB - вычисляется в int, и никакой дополнительной информации не предоставляется, компилятор понимает, что результатом данного выражения должен быть возвращаемый тип метода.

В длинном варианте тогда код, в котором используется это лямбда-выражение, можно было бы расширить до следующего кода, в котором используется уже анонимный метод:

Console.WriteLine( f(а, b) = а + b: ); PerformOperations (delegate (int paraxnA, int paramB) {

return paramA + paramB;

В остальной части кода выполняются операции с использованием двух разных лямбда-выражений одинаковым образом:

Console.WriteLine() ;

Console.WriteLine( f(а, b) = а * b: );

PerformOperations((paramA, paramB) => paramA * paramB); Console.WriteLine();

Console.WriteLine( f(a, b) = (a - b) % b: );

PerformOperations((paramA, paramB) => (paramA - paramB) % paramB); Console.ReadKey 0;

Последнее лямбда-выражение подразумевает больше вычислений, но сложнее других от этого не становится. Синтаксис лямбда-выражений позволяет выполнять и гораздо более сложные операции, как будет показано ниже.



Параметры лямбда-выражений

в коде, который демонстрировался до сих пор, в лямбда-выражениях для определения типов передаваемых параметров применялся механизм выведения типов. На самом деле, обязательным это не является; при желании типы параметров можно и определять. Например, можно было бы использовать и такое лямбда-выражение:

(int paramA, int paramB) => paramA + paramB

При таком подходе код получается более удобочитаемым, но утрачивает краткость и гибкость. Лямбда-выражения с неявным определением типов из предыдущего практического занятия можно было бы использовать для типов делегатов с другими числовыми типами, например, long.

Обратите внимание на то, что использовать и неявные и явные типы параметров в одном и том же лямбда-выражении нельзя. Следующее лямбда-выражение компилироваться не будет, потому что тип параметра paramA в нем определяется явно, а параметра paramB - неявно:

(int paramA, paramB) => paramA + paramB

Списки параметров в лямбда-выражениях всегда состоят из разделенного запятыми перечня либо всех неявно типизированных, либо всех явно типизированных параметров. Если параметр только один, тогда круглые скобки могут опускаться; в противном случае они являются обязательной частью списка параметров, как в показанном выше примере. Например, лямбда-выражение с единственным неявно типизированным параметром может выглядеть так:

paraml => paraml * paraml

Еще можно определять лямбда-выражения, не имеющие параметров. Отсутствие параметров обозначается пустыми круглыми скобками, как показано ниже:

О => Math.PI

Такое выражение могло бы пригодиться при необходимости в использовании делегата, не требующего никаких параметров, но возвращающего значение double.

Тело операторов лямбда-выражений

Во всем приводившемся пока что коде в теле оператора лямбда-выражений использовалось единственное выражение. Это выражение воспринималось как возвращаемое значение лямбда-выражения, что и показывает то, как, к примеру, выражение paramA + paramB можно применять в качестве тела оператора для лямбда-выражения, предназначенного для делегата с возвращаемым типом int (при условии приведения обоих параметров paramA и paramB явным или неявным образом к int, как это и было сделано в примере кода).

Еще в одном из прежних примеров было показано, как делегат с возвращаемым типом void позволяет использовать менее громоздкий код в теле оператора:

myTimer.Elapsed += (source, е) => Console.WriteLine (

Event handler called after {0} milliseconds. , (source as Timer).Interval);

Здесь оператор ни во что не вычисляется, и потому будет выполняться без использования возвращаемого значения.

С учетом того, что лямбда-выражения могут визуализироваться в виде расширения синтаксиса анонимных методов, вряд ли покажется удивительным то, что в виде части тела операторов лямбда-выражений можно также использовать и множество операторов. Осуществляется это путем предоставления заключенного в фигурные скобки



кода, во многом подобно тому, как это делается в любых других ситуациях в С#, когда требуется предоставлять несколько строк кода:

(paraml, param2) => {

Здесь идет несколько операторов.

В случае использования лямбда-выражения в сочетании с делегатом, возвращаемым типом которого является не void, нужно обязательно выполнять возврат значения с помощью ключевого слова return, точно так же как и в любом другом методе:

(paraml, param2) => {

Здесь идет несколько операторов! return возвращаемое значение;

Например, ранее уже показывалось, что следующий код из практического занятия:

PerformOperations((paramA, paramB) => paramA + paramB); МОЖНО было бы переписать так:

PerformOperations(delegate(int paramA, int paramB) {

return paramA + paramB;

В качестве альтернативного варианта, этот код можно было бы переписать и следующим образом:

PerformOperations((рагашА, paramB) =>

return paramA + paramB;

В этом случае достигается большая преемственность с исходным кодом, поскольку сохраняется неявная типизация параметров paramA и paramB.

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

Лямбда-выражения как делегаты и как деревья выражений

Некоторые отличия между лямбда-выражениями и анонимными методами, вроде того, что лямбда-методы обладают большей гибкостью (например, могут иметь неявно типизированные параметры), уже были показаны. Теперь пришла пора рассказать о еще одном важном отличии, последствия которого, однако, прояснятся лишь позже в книге, при изучении технологии LINQ.

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



1 ... 132 133 134 [ 135 ] 136 137 138 ... 396

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика