English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Лямбда-выражения LINQ

C# 3.0 (.NET 3.5) ввел лямбда-выражения и LINQ. Лямбда-выражения - это более короткий способ представления анонимных методов с помощью некоторых специальных синтаксисов.

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

delegate(Student s) { return s.Age > 12 && s.Age < 20; };
Dim isStudentTeenAger = Function(s As Student) As Boolean
                                    Возврат s.Age > 12 And s.Age < 20
                        End Function

Использование лямбда-выражений в C# и VB.Net для представления анонимных методов, как показано ниже:

s => s.Age > 12 && s.Age < 20
Function(s) s.Age > 12 And s.Age < 20

Давайте посмотрим, как Lambda-выражение возникло из следующего анонимного метода.

delegate(Student s) { return s.Age > 12 && s.Age < 20; };

Lambda-выражение возникло из анонимного метода, сначала удалив ключевое слово делегата и тип параметра, и добавив оператор lambda =>

Lambda-выражение из анонимного метода

Указанное выше Lambda-выражение绝对是 действительным, но если у вас есть только один оператор возвращения значения, вам не нужно использовать фигурные скобки, return и точку с запятой. Таким образом, мы можем удалить его.

Кроме того, если у вас есть только один параметр, вы можете удалить скобки ()

Lambda-выражение из анонимного метода

Таким образом, мы получили Lambda-выражение: s => s.Age > 12 && s.Age < 20, гдеsЭто параметр,=>Это оператор lambda,s.Age > 12 && s.Age < 20Это выражение тела:

Структура Lambda-выражения в C#

Способ получения Lambda-выражения в VB.Net может быть следующим:

Структура Lambda-выражения в VB.Net

Способ вызова Lambda-выражения такой же, как и вызов делегата с использованием скобок ()

Обратите внимание: VB.Net не поддерживает оператор lambda =>

Lambda-выражение с несколькими параметрами

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

    Пример: Указание нескольких параметров в Lambda-выражении C#

(s, youngAge) => s.Age >= youngage;

Если параметр неясен, вы можете указать тип каждого параметра:

(Student s, int youngAge) => s.Age >= youngage;
Пример: Указание нескольких параметров в Lambda-выражении VB.Net
Function(s, youngAge) s.Age >= youngAge

Lambda-выражение без параметров

Lambda-выражение не обязано иметь по крайней мере один параметр. Lambda-выражение также может быть указано без каких-либо параметров.

() => Console.WriteLine("Lambda-выражение без параметров")

Множественные предложения в теле Lambda-выражения

Если нужно включить несколько предложений в的主体, можно обернуть выражение фигурными скобками:

(s, youngAge) =>{
  Console.WriteLine("Выражение-lambda с несколькими строками в теле");
    
  Return s.Age >= youngAge;}
Function(s, youngAge)
    
    Console.WriteLine("Выражение-lambda с несколькими строками в теле");
    
    Return s.Age >= youngAge
End Function

Объявление локальных переменных в теле выражения-lambda

Вы можете объявить переменную в теле выражения, чтобы использовать её в любом месте тела выражения, например:

s =>
{ int youngAge = 18;
    Console.WriteLine("Выражение-lambda с несколькими строками в теле");
    return s.Age >= youngAge;
}
Function(s) 
                                      
        Dim youngAge As Integer = 18
            
        Console.WriteLine("Выражение-lambda с несколькими строками в теле");
            
        Return s.Age >= youngAge
            
End Function

Выражение-lambda также можно назначить встроенным делегатам, таким как Func, Action и Predicate.

Назначение выражения-lambda делегату

Вы можете назначить выражение-lambda типу делегата Func<in T, out TResult>. Последний параметр типа делегата Func является типом возвращаемого значения,其余 параметры являются входными параметрами.Обратитесь к разделу Func делегата руководства по C# для получения дополнительной информации.

Рассмотрим следующий выражение-lambda, чтобы понять, является ли студент подростком.

Func<Student, bool> isStudentTeenAger = s => s.age > 12 && s.age < 20;
Student std = new Student() { age = 21 };
bool isTeen = isStudentTeenAger(std); // возвращается false
Dim isStudentTeenAger As Func(Of Student, Boolean) = Function(s) s.Age > 12 And s.Age < 20
Dim stud As New Student With {.Age = 21}
Dim isTeen As Boolean = isStudentTeenAger(stud) // возвращается false

В примере выше делегат Func ожидает первого входного параметра типа Student, а тип возвращаемого значения - булево. Лямбда-выражение s => s.age > 12 && s.age < 20 соответствует требованиям делегата Func<Student, bool>, как показано ниже:

Делегат Func с лямбда-выражением

Показанный выше делегат Func <> станет функцией, как показано ниже.

bool isStudentTeenAger(Student s)
{
    return s.Age > 12 && s.Age < 20;
}

Делегат действия

В отличие от делегата FuncДелегат действияДелегат действия может иметь только один входной параметр. Когда вам не нужно возвращать из лямбда-выражения никакие значения, используйте тип делегата Action.

Action<Student> PrintStudentDetail = s => Console.WriteLine("Name: {0}, Age: {1} ", s.StudentName, s.Age);
Student std = new Student() { StudentName = "Bill", Age = 21 };
PrintStudentDetail(std)//вывод: Name: Bill, Age: 21
Dim printStudentDetail As Action(Of Student) = Sub(s) Console.WriteLine("Name: {0}, Age: {1} ", s.StudentName, s.Age)
    
Dim stud As New Student With {.StudentName = "Bill", .Age = 21}
        
printStudentDetail(stud)//вывод: Name: Bill, Age: 21

Лямбда-выражения в LINQ-запросах

Обычно, лямбда-выражения используются вместе с LINQ-запросами. К статическим классам, подлежащим итерации, относятся расширяемые методы IEnumerable<T> where, которые принимают Func<TSource, bool>. Поэтому, расширяемый метод Where() IEnumerable<Student> требует Func<Student, bool>, как показано ниже:

Параметр делегата Func в методе расширения Where()

Таким образом, теперь вы можете передавать лямбда-выражение, присвоенное делегату Func, методу расширения Where() следующим образом:

IList<Student> studentList = new List<Student>(){...};
Func<Student, bool> isStudentTeenAger = s => s.age > 12 && s.age < 20;
var teenStudents = studentList.Where(isStudentTeenAger).ToList<Student>();
IList<Student> studentList = new List<Student>(){...};
Func<Student, bool> isStudentTeenAger = s => s.age > 12 && s.age < 20;
var teenStudents = from s in studentList
                   where isStudentTeenAger(s)
                   select s;

Вы можете следовать тому же методу в VB.Net, чтобы передать делегат Func.

Важно помнить

  1. Лямбда-выражение - это кратковременный способ записи анонимного метода.

  2. Синтаксис лямбда-выражений: Параметр => тело выражения

  3. Lambda-выражение может иметь нулевые параметры.

  4. В скобках () лямбда-выражения могут быть несколько параметров.

  5. Lambda-выражение может содержать несколько инструкций в теле выражения, заключенном в фигурные скобки {}.

  6. Lambda-выражение можно присвоить делегату Func, Action или Predicate.

  7. Lambda-выражение можно вызывать, как и делегат.