Lambda表达式

来源:互联网 发布:python for line in f 编辑:程序博客网 时间:2024/06/03 14:24

一、匿名方法:

匿名方法实际上并非传统意义上的方法,它不是某个类上的方法,而纯粹是为用作委托目的而创建的。

要创建匿名方法,需要使用下面的代码:

delegate(parameters)

{

// Anonymous method code.

};

其中parameters 是一个参数列表,这些参数匹配正在实例化的委托类型,由匿名方法的代码使用,例如:

myConnection1.MessageArrived +=delegate(Connection source, MessageArrivedEventArgs e)

{

Console.WriteLine("Message arrived from: {0}", source.Name);

Console.WriteLine("Message Text: {0}", e.Message);

};

二、Lambda表达式:

Lambda 表达式是C# 3.0 引入的一个结构,可用于简化C#编程的某些方面,尤其是与LINQ 合

并的方面。此匿名方法是介绍Lambda 表达式的最佳切入点,我们先来看一个用delegate 关键字定义内联的匿名方法:

myTimer.Elapsed +=delegate(object source, ElapsedEventArgs e)

{

Console.WriteLine(

"Event handler called after {0} milliseconds.",

(source as Timer).Interval);

};

这段代码可以正常工作,且使用了事件处理程序。主要区别是这里使用的匿名方法对于其余代码而言实际上是隐藏的。例如,不能在应用程序的其他地方重用这个事件处理程序。另外,为了更好地加以描述,这里使用的语法有点沉闷。delegate 关键字总是会带来混淆,因为它有双重含义——匿名方法和定义委托类型都要使用它。

三、把Lambda表达式用于匿名方法

Lambda 表达式是简化匿名方法的语法的一种方式。实际上,Lambda表达式还有其他用处。

使用Lambda 表达式可以重写上面的一段代码,如下所示:

myTimer.Elapsed += (source, e) => Console.WriteLine(

"Event handler called after {0} milliseconds.",(source as Timer).Interval);

仔细观察,就会看出Lambda 表达式由3 个部分组成:

l 1)放在括号中的参数列表(未类型化)

l 2)=>运算符

l 3)C#语句

=>运算将只是把参数列表与表达式体分开。在调用Lambda 表达式时,执行表达式体。

编译器会提取这个Lambda 表达式,创建一个匿名方法,其工作方式与匿名方法相同。其实,它会被编译为相同或相似的CIL 代码。

四、Lambda表达式的参数:

在前面的代码中,Lambda 表达式使用类型推理功能确定所传送的参数类型。实际上这不是必须的,也可以定义类型。例如,可以使用下面的Lambda 表达式:

(int paramA, int paramB) => paramA + paramB

其优点是代码更容易理解,但不够简明灵活。在前面委托类型的示例中,可以通过隐式类型化的 Lambda 表达式来使用其他数字类型。

注意,不能在同一个Lambda 表达式中同时使用隐式和显式的参数类型。下面的Lambda 表达式就不会编译,因为paramA 是显式类型化的,而paramB 是隐式类型化的:

(int paramA, paramB) => paramA + paramB

Lambda 表达式的参数列表总是包含一个用逗号分隔的列表,其中的参数要么都是显式类型化的,要么都是隐式类型化的。如果只有一个参数,就可以省略括号;否则就需要在参数列表上加上括号。

param1 => param1 * param1

还可以定义没有参数的Lambda 表达式,这使用空括号来表示:

() => Math.PI

Lambda表达式的语句体:

Lambda 表达式可以看作匿名方法语法的扩展,所以还可以在Lambda 表达式的语句体中包含多个语句。如果使用Lambda 表达式和返回类型不是void 的委托类型,就必须用return 关键字返回一个值,这与其他方法一样:

(param1, param2) =>

{

// Multiple statements ahoy!

return returnValue;

}

在大多数情况下,使用单一的表达式时,大都使用Lambda 表达式,它们肯定是最简洁的。

五、Lambda表达式用作委托和表达式树:

可以用两种方式来解释Lambda 表达式。第一,如上面所述,Lambda 表达式是一个委托。即可以把Lambda 表达式赋予一个委托类型的变量。

一般可以把拥有至多8 个参数的Lambda 表达式表示为如下泛型类型,它们都在System 命名空间中定义:

l1) Action 表示的Lambda 表达式不带参数,返回类型是void

l2) Action<>表示的Lambda 表达式有至多8 个参数,返回类型是void

l3) Func<>表示的Lambda 表达式有至多8 个参数,返回类型不是void

Action<>有至多8 个泛型类型的参数,分别用于Lambda 表达式的8 个参数,Func<>有至多9个泛型类型的参数,分别用于Lambda 表达式的8 个参数和返回类型。在Func<>中,返回类型总是在列表的最后。例如,下面的Lambda 表达式:

(int paramA, int paramB) => paramA + paramB

可以表示为Func<int, int, int>类型的委托,因为它有两个int 参数,返回类型是int。

第二,可以把Lambda 表达式解释为表达式树。表达式树是Lambda 表达式的抽象表示,但不能直接执行。可以使用表达式树以编程方式分析Lambda 表达式,执行操作,以响应Lambda 表达式。显然这是一个复杂的主题,但表达式树和LINQ 功能至关重要。LINQ 架构包含一个泛型类Expression<>,可用于封装Lambda 表达式。使用这个类的一种方式是提取用C#编写的Lambda 表达式,把它转换为相应的SQL 脚本,以便在数据库中直接执行。