C#3.0(.NET 3.5)引入了lambda表达式以及 LINQ。lambda表达式是使用某些特殊语法表示匿名方法的一种较短方法。
例如,采用以下匿名方法检查学生是否为青少年:
delegate(Student s) { return s.Age > 12 && s.Age < 20; };
Dim isStudentTeenAger = Function(s As Student) As Boolean Return s.Age > 12 And s.Age < 20 End Function
可以使用C#和VB.Net中的Lambda表达式来表示上述匿名方法,如下所示:
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表达式绝对有效,但是如果我们只有一个返回值的语句,则不需要花括号,return和分号。因此我们可以删除它。
另外,如果只有一个参数,则可以删除括号()。
因此,我们得到了lambda表达式:s => s.Age > 12 && s.Age < 20 其中s是参数,=>是lambda运算符,s.Age > 12 && s.Age < 20是表达式主体:
我们在VB.Net中获得lambda表达式的方式可以如下编写:
lambda表达式的调用方式与使用()的委托调用方式相同。
注意:VB.Net不支持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表达式也可以不带任何参数来指定。
() => Console.WriteLine("无参数 lambda 表达式")
如果要在主体中包含多个语句,可以将表达式用大括号括起来:
(s, youngAge) =>{ Console.WriteLine("在主体中包含多个语句的Lambda表达式"); Return s.Age >= youngAge;}
Function(s , youngAge) Console.WriteLine("在主体中包含多个语句的Lambda表达式") Return s.Age >= youngAge End Function
您可以在表达式主体中声明一个变量,以在表达式主体中的任何地方使用它,如下所示:
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表达式分配给Func<in T, out TResult>委托类型。Func委托中的最后一个参数类型是返回类型,其余参数是输入参数。访问C#教程的Func委托部分以了解更多信息。
考虑以下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类型,而返回类型为布尔值。lambda表达式 s => s.age > 12 && s.age < 20满足Func <Student,bool>委托要求,如下所示:
上面显示的Func <>委托将变成一个如下所示的函数。
bool isStudentTeenAger(Student s) { return s.Age > 12 && s.Age < 20; }
与Func委托不同,Action委托只能具有输入参数。当您不需要从lambda表达式返回任何值时,请使用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
通常,lambda表达式与LINQ查询一起使用。可枚举的静态类包括其中的扩展方法IEnumerable<T>wheres接受Func<TSource,bool>。因此,收集的Where()扩展方法IEnumerable<Student>需要通过Func<Student,bool>,如下所示:
因此,现在,您可以使用Where()如下所示的方法语法将分配给Func委托的lambda表达式传递给扩展方法:
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委托。
Lambda表达式是表示匿名方法的简写方法。
Lambda表达式语法: 参数 => 表达式主体
Lambda表达式可以具有零参数。
Lambda表达式的括号()中可以有多个参数。
Lambda表达式可以在大括号{}中的主体表达式中包含多个语句。
Lambda表达式可以分配给Func,Action或Predicate委托。
可以以类似于委托的方式调用Lambda Expression。