Lambda 表达式
早在
C# 1.0 时,C#中就引入了委托(delegate)类型的概念。通过使用这个类型,我们可以
将函数作为参数进行传递。在某种意义上,委托可理解为一种托管的强类型的函数指针。
通常情况下,使用委托来传递函数需要一定的步骤:
1)
定义一个委托,包含指定的参数类型和返回值类型。
2)
在需要接收函数参数的方法中,使用该委托类型定义方法的参数签名。
3)
为指定的被传递的函数创建一个委托实例。
可能这听起来有些复杂,不过本质上说确实是这样。上面的第
3 步通常不是必须的,C# 编
译器能够完成这个步骤,但步骤
1 和 2 仍然是必须的。
幸运的是,在
C# 2.0 中引入了泛型。现在我们能够编写泛型类、泛型方法和最重要的:泛型
委托。尽管如此,直到
.NET 3.5,微软才意识到实际上仅通过两种泛型委托就可以满足 99%
的需求:
Action :无输入参数,无返回值
Action<T1, ..., T16> :支持 1-16 个输入参数,无返回值
Func<T1, ..., T16, Tout> :支持 1-16 个输入参数,有返回值
Action 委托返回 void 类型,Func 委托返回指定类型的值。通过使用这两种委托,在绝大多
数情况下,上述的步骤
1 可以省略了。但是步骤 2 仍然是必需的,但仅是需要使用 Action
和
Func。
那么,如果我只是想执行一些代码该怎么办?在
C# 2.0 中提供了一种方式,创建匿名函数
但可惜的是,这种语法并没有流行起来。下面是一个简单的匿名函数的示例:
Func<
double
,
double
> square =
delegate
(
double
x)
{
return
x * x;
};
为了改进这些语法,在
.NET 3.5 框架和 C# 3.0 中引入了 Lambda 表达式。
首先我们先了解下
Lambda 表达式名字的由来。实际上这个名字来自微积分数学中的 λ,其
涵义是声明为了表达一个函数具体需要什么。更确切的说,它描述了一个数学逻辑系统,通
过变量结合和替换来表达计算。所以,基本上我们有
0-n 个输入参数和一个返回值。而在编
程语言中,我们也提供了无返回值的
void 支持。
让我们来看一些
Lambda 表达式的示例:
1
//
The compiler cannot resolve this, which makes the usage of var impossible!
2
//
Therefore we need to specify the type.
3
Action dummyLambda = () =>