Lambdas with the Standard Query Operators



Many Standard query operators have an input parameter whose type is one of the Func<<(Of <T, TResult>>)> family of generic delegates. The Func<<(Of <T, TResult>)>> delegates use type parameters to define the number and type of input parameters, and the return type of the delegate. Func delegates are very useful for encapsulating user-defined expressions that are applied to each element in a set of source data. For example, consider the following delegate type:

public delegate TResult Func<TArg0, TResult>(TArg0 arg0)

The delegate can be instantiated as Func<int,bool> myFunc where int is an input parameter and bool is the return value. The return value is always specified in the last type parameter. Func<int, string, bool> defines a delegate with two input parameters, int and string, and a return type of bool. The following Func delegate, when it is invoked, will return true or false to indicate whether the input parameter is equal to 5:

Func<int, bool> myFunc = x => x == 5; bool result = myFunc(4); // returns false of course

Лямбды операторов

Лямбда оператора напоминает выражение-лямбду, за исключением того, что оператор (или операторы) заключается в фигурные скобки.

(input parameters) => {statement;}

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

delegate void TestDelegate(string s); … TestDelegate myDel = n => { string s = n + " " + "World"; Console.WriteLine(s); }; myDel("Hello");

Лямбды операторов, как и анонимные методы, не могут использоваться для создания деревьев выражений.

Лямбды со стандартными операторами запросов

Многие стандартные операторы запросов имеют параметр ввода, тип которого принадлежит семейству Func<(Of <(T, TResult>)>) общих делегатов. Делегаты Func<(Of <(T, TResult>)>) используют параметры типов для определения числа и типа параметров ввода и возвращают тип делегата. Делегаты Func очень полезны при инкапсулировании пользовательских выражений, которые применяются к каждому элементу в наборе исходных данных. В качестве примера рассмотрим следующий тип делегата.

public delegate TResult Func<TArg0, TResult>(TArg0 arg0)

Можно создать экземпляр этого делегата как Func<int,bool> myFunc, где int — параметр ввода, а bool — возвращаемое значение. Возвращаемое значение всегда указывается в последнем параметре типа. Func<int, string, bool> определяет делегат с двумя параметрами ввода, int и string, и возвращает тип bool. Следующий делегат Func при вызове возвращает значение true или false, которое показывает, равен ли параметр ввода 5.

Func<int, bool> myFunc = x => x == 5; bool result = myFunc(4); // returns false of course

 


You can also supply a lambda expression when the argument type is an Expression<Func>, for example in the standard query operators that are defined in System.Linq.Queryable. When you specify an Expression<Func> argument, the lambda will be compiled to an expression tree.

A standard query operator, the Count method, is shown here:

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; int oddNumbers = numbers.Count(n => n % 2 == 1);

The compiler can infer the type of the input parameter, or you can also specify it explicitly. This particular lambda expression counts those integers (n) which when divided by two have a remainder of 1.

The following method will produce a sequence that contains all the elements in the numbers array that occur before the “6” because that is the first number in the sequence that does not meet the condition:

var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6);

This example shows how to specify multiple input parameters by enclosing them in parentheses. The method returns all the elements in the numbers array until a number is encountered whose value is less than its position. Do not confuse the lambda operator (=>) with the greater than or equal operator (>=).

var firstSmallNumbers = numbers.TakeWhile((n, index) => n >= index);

Type Inference in Lambdas

When writing lambdas, you often do not have to specify a type for the input parameters because the compiler can infer the type based on the lambda body, the underlying delegate type, and other factors as described in the C# 3.0 Language Specification. For most of the standard query operators, the first input is the type of the elements in the source sequence. So if you are querying an IEnumerable<Customer>, then the input variable is inferred to be a Customer object, which means you have access to its methods and properties:

customers.Where(c => c.City == "London");

The general rules for lambdas are as follows:

· The lambda must contain the same number of parameters as the delegate type.

· Each input parameter in the lambda must be implicitly convertible to its corresponding delegate parameter.

· The return value of the lambda (if any) must be implicitly convertible to the delegate's return type.

Note that lambda expressions in themselves do not have a type because the common type system has no intrinsic concept of "lambda expression." However, it is sometimes convenient to speak informally of the "type" of a lambda expression. In these cases the type refers to the delegate type or Expression type to which the lambda expression is converted.


Также лямбда-выражения можно использовать, когда аргумент имеет тип Expression<Func>, например в стандартных операторах запроса, как указано в System.Linq.Queryable. При определении аргумента Expression<Func> лямбда компилируется в дерево выражения.

Стандартный оператор запроса, метод Count, показан ниже.

ß---

Компилятор может вывести тип параметра ввода; также его можно определить явно. Данное лямбда-выражение подсчитывает указанные целые значения (n), которые при делении на два дают остаток 1.

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

var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6);

В этом примере показано, как определить несколько параметров ввода путем их заключения в скобки. Этот метод возвращает все элементы в массиве чисел до того числа, величина которого меньше номера его позиции. Не следует путать лямбда-оператор (=>) с оператором "больше или равно" (>=).


Дата добавления: 2019-03-09; просмотров: 212; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!