从匿名方法到 Lambda 表达式的推演过程

Posted laopo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从匿名方法到 Lambda 表达式的推演过程相关的知识,希望对你有一定的参考价值。

Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数。 通过使用 lambda 表达式,可以写入可作为参数传递或作为函数调用值返回的本地函数。 以上是msdn官网对Lambda 表达式的描述。实质上Lambda 表达式可以说是从匿名方法推演而来,微软程序员为了提高我们广大程序员的生产效率推出了Lambda 表达式,它的出现无疑是极具影响力的。

Lambda 表达式使用Lambda 运算符=>,我们一般读作“goes to”,当然这并不是说它跟C#中的goto有相同的含义,只是都有“转到”的意思罢了。Lambda 表达式的书写规则如下:

参数列表=>表达式

现在就让我来讲解下从匿名方法到Lambda 表达式的推演过程。以上篇博文的例子为例,

//假设需要从list集合中获取大于3的所有元素以新集合返回
List<int> list = new List<int>()  1, 2, 3, 4, 5, 6 ;
var newlist = list.FindAll(delegate(int i)  return i > 3; );

这是用匿名方法实现的写法。微软程序员觉得这样子不够简单,为了简便写法,便有了如下的推断过程。

首先既然你总是要传入一个匿名方法,总是会有delegate这个关键字,于是可以考虑将delegate去掉。去掉了delegate,那么书写就不规范了,于是就引入了=>运算符用来连接参数列表与表达式,这样上式便变成:

var newlist = list.FindAll((int i) =>  return i > 3; );

其次,int这个类型是可以推断出来的,当用鼠标指到"FindAll"的时候就可以看到:

技术图片

这便让我们知道这里delegate后续的入参是int型(本例是int型,因为上面的集合是int型,实际上什么类型是看你自己需求的),于是再指定类型为int显得有点多余,因此可以写成这样:

var newlist = list.FindAll((i) =>  return i > 3; );

而此时参数只有一个,因此括号也可以去掉:

var newlist = list.FindAll(i =>  return i > 3; );
然后,FindAll()需要传入一个Predicate<T>泛型委托,可以按F12看出该委托返回值类型为bool,
同样我们传入的匿名方法必须与它具有相同的签名,所以也要返回bool值。因为总是知道要返回什么类型的值,所以可以考虑去掉return关键字,而方法体里只有一句表达式,所以可以考虑去掉大括号,同时也将表达式后面多余的分号去掉,
到了这个时候原本的方法体已变成i>3这么个表达式,其等价于一个bool值,可以类比if(i>3)来理解,
多个return关键字不过是为了返回值以符合方法定义的规范。于是原来的式子又演变成了:
var newlist = list.FindAll(i => i > 3 );

看了上面的例子或许有人会有这样的疑惑,=>右边就只能写一句表达式,那么如果我要执行很复杂的逻辑怎么办?事实上,可以这样写:

List<int> newlist = list.FindAll( (int i) =>//小括号和int可以同时省略,也可以只省略int,不能只省略小括号留int
            
                //这里可以写复杂的逻辑,下面只是示例,当然可以直接return i>3;效果和上面的一样
                Console.WriteLine("原集合有如下数字:0", i);
                bool b = i > 3;
                return b;
            );

之前的例子是因为 =>左边的参数只有一个才可以省略小括号,实际上,当参数不止一个的时候,则不能省略小括号,例如:(i,j)=>表达式或语句块

如果没有参数,可以这样写:()=>表达式或语句块

从匿名方法到Lambda 表达式可以说一个优化演变的过程,Lambda 表达式是一个委托类型,它和匿名方法一样可以传递为委托参数

以上是关于从匿名方法到 Lambda 表达式的推演过程的主要内容,如果未能解决你的问题,请参考以下文章

Lambda 表达式与匿名内部类

.net 中 委托的解析泛型解析可变性解析表达式和匿名方法基invoke的用法()

.net 中 委托的解析泛型解析可变性解析表达式和匿名方法基invoke的用法()

匿名方法是怎样演变到Lambda表达试过程

1. lamda匿匿名函数 2. sorted() 3. ?lter() 4. map() 5. 递归函数

还有好多要掌握的