C# 3.0(.NET 3.5) 与 LINQ 一起引入了 lambda 表达式。 lambda 表达式是使用一些特殊语法表示匿名方法的一种更短的方式。 (js里把它叫箭头函数,两个是类似的东西)
例如,以下匿名方法检查学生是否为青少年:
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
static void Main(string[] args)
{
Predicate<Student> predicate = delegate (Student s) { return s.Age > 12 && s.Age < 20; };
}
上述匿名方法可以使用 C# Lambda 表达式表示如下:
class Program
{
static void Main(string[] args)
{
Predicate<Student> predicate = s => s.Age > 12 && s.Age < 20;
}
}
让我们看看 lambda 表达式是如何从以下匿名方法演变而来的
匿名方法
delegate (Student s) { return s.Age > 12 && s.Age < 20; };
Lambda 表达式是从匿名方法演变而来,首先删除了委托关键字和参数类型,并添加了一个 lambda 运算符 =>。
static void Main(string[] args)
{
Predicate<Student> predicate = delegate (Student s) { return s.Age > 12 && s.Age < 20; };
// 把 delegate 去掉了 加入了 => 关键的一步。换了一种表达方式而已
Predicate<Student> predicate2 = (Student s) => { return s.Age > 12 && s.Age < 20; };
// 把类型去掉了。因为是可以推断出来的。
Predicate<Student> predicate3 = (s) => { return s.Age > 12 && s.Age < 20; };
//因为只有一个语句,所以 return 和大括号也可以被省略
Predicate<Student> predicate4 = (s) => s.Age > 12 && s.Age < 20;
// 因为只有一个参数所以 括号也可以补省略
Predicate<Student> predicate5 = s => s.Age > 12 && s.Age < 20;
}
因此,我们得到了 lambda 表达式: s => s.Age > 12 && s.Age < 20 其中 s 是一个参数, => 是 lambda 运算符, 而 s.Age > 12 && s.Age < 20 是主体表达式 :
//类型参数可以省是因为左边有定义了,所以推断得出来
Func<Student, int, bool> func = (s, minAge) => { return s.Age > minAge && s.Age < 20; };
一个 lambda 表达式中没有必要至少有一个参数。 也可以不带任何参数指定 lambda 表达式。
Action action = () => Console.WriteLine("hello world");
大括号和 return 不能省略了
Predicate<Student> predicate6 = (s) =>
{
s.Age += 10;
return s.Age > 12 && s.Age < 20;
};
Predicate<Student> predicate7 = (s) =>
{
var maxAge = 20;
return s.Age > 12 && s.Age < maxAge;
};
var maxAge = 20;
Predicate<Student> predicate8 = (s) =>
{
return s.Age > 12 && s.Age < maxAge;
};
有了这个之后我们基本上不会按匿名方法的方式来写代码了。