lambda表达式之进化

前言

在C#我们可以自定义委托,但是C#为什么还要内置泛型委托呢?因为我们常常要使用委托,如果系统内置了一些你可能会用到的委托,那么就省去了定义委托,然后实例化委托的步骤,这样一来既使代码看起来简洁而干净又能提高程序员的开发速度,何乐不为呢!通过本文可以让你复习扩展方法,同时可以循序渐进的了解系统内置泛型委托的实现以及委托逐步的演化过程。

 Action

概念:封装一个方法,该方法具有五个参数并且不返回值。并且类型参数为逆变

下面我就自定义实现一个Action无返回值的委托。我们同样定义一个Person类,似乎我随笔中永远都离不开Person的话题,哈哈!请看如下代码

然后在控制台中通过 ForEach 方法模拟Action委托,先定义一个获得Person的列表GetList()

因为我们知道在用委托时,有这样几个步骤:

(1)定义委托

(2)实例化委托

(3)将方法指针添加到实例化委托对象中

但是现在我们无需定义委托,已经有了内置委托,只需将其实例化即可,同时添加方法的指针一般是有明确的方法,如果我们只是临时的用方法,这时就可以派匿名方法上场了,所以上面三步就可以简化成两步。代码如下:

上述代码颇有点JQuery中Each的遍历方法的意味。结果打印出:

我们知道ForEach这个方法里面的的参数就是 Action action ,所以我们可以直接进行如下简写

其打印结果和上面是一样的。其代码可以继续进行更加的精简,不着急,我们循序渐进的来。

Predicate

概念:定义一组条件并确定指定对象是否符合这些条件的方法。返回值为bool类型,并且类型参数为逆变。

用到此泛型委托莫过于List中的 FindAll() 方法了,它就是从一个集合中根据条件筛选出一个新的集合出来。上节刚好学过扩展方法,我们可以自定义实现这个方法用扩展方法加在泛型集合List上根据  Predicate 委托的参数条件进行筛选。

我们查询出年纪大于13岁的并且根据ForEach来遍历筛选出来的数据,代码如下:

结果打印出正确的结果,如下:

而通过C#中的FindAll,则只需如下做即可同样达到上述的效果,只是不是扩展方法罢了:

上述代码其实可以更加精简,不着急,我们一步一步循序渐进的来。

Comparison

概念:表示比较同一类型的两个对象的方法。参数类型为逆变,返回值为int。

同样可以简写为:

Func

貌似在系统内置泛型委托中Func在实际项目开发中是使用的最多的。

概念:封装一个具有一个参数并返回 TResult 参数指定的类型值的方法。参数类型为逆变,返回值参数类型为协变。

用到此委托的最多的就是List泛型集合中的 Select 方法了,看看内置的Select方法是如何利用Func来实现返回一个新的集合的。

(1)结合匿名方法实现

我们接下来在上面基础上再定义一个Animal类。属性和Person类一样,代码如下:

接下来我们就通过Select方法通过Person的集合来返回一个新的集合即Animal集合。代码如下:

同样打印出当遍历Person集合时的结果一样,看起来似乎很繁琐,我们将代码通过进行精简如下:

下面我们通过扩展方法来自定义实现Select()方法,代码如下:


依然是进行此调用,打印结果正确:

 (2)结合匿名类来实现

当我们使用Func根据条件转换成新的集合时可能只需要几个实例成员,这个时候如果还重新建立一个类来进行获取就显得有点小题大做了,这个时候只需将其需要的或的成员传给一个匿名类即可,这个就是Func需要用到匿名类的场景。所以鉴于此,我们将返回的新的集合为匿名集合而非Animal集合,代码改造如下:

通过上述所讲系统内置泛型委托的实现,似乎有点不太令人满意,关于委托的代码太过繁琐,是的微软大大也明确知道了这点,于是乎,一步一步走向了高级,那就下文的lambda表达式,这结构的简单简直了。。。让你爽到暴。

lambda表达式

上述代码说过可以精简,如何精简呢?那就是lambda表达式,匿名方法已经够简洁的了,但是lambda表达式是比匿名方法更加简洁的一种语法!我们用lambda表达式来分别实现上述中的Action、Predicate以及Func委托。

Action

Predicate

Func

好了,一切都变得如此明朗。自从有了lambda表达式,敲代码的速度加快了,妈妈再也不用担心我熬夜到很晚了。

好了,问题来了,我们知道lambda表达式分为 语句lambda和表达式lambda  ,那么二者有何区别呢?从字面上理解语句lambda是不是就是用大括号括起来的呢?ok,给出代码来理解吧。

那问题又来了,lambda表达式到底是什么呢?我们依然用反编译来查看  list.ForEach(d => Console.WriteLine(d.Age)); 对应的C#代码如下:

看ForEach()方法里面的参数意思大概是匿名方法委托,接着我们点击进去看看,代码如下:

我们接着点击Action看看,如下:

一下就豁然开朗了,这不正说明 lambda表达式的实质就是匿名方法 吗!所以现在想想,lambda表达式的本质是匿名方法,匿名方法的本质是通过委托实现的。应该就是这样了。

lambda表达式进化过程

我们就一个扩展方法的实例来演示lambda表达式演变的过程是多么的惟妙惟肖。

假设如下场景:在花千骨电视中找出白子画出来,找对了你就赢了!我们获得给出一个花千骨众角色列表,再选出白子画即可。

下面给出集合列表:

然后在控制台执行扩展方法进行查询,在此列出 lambda表达式6部曲 :

从开始的繁琐,复杂到最终的简洁,每一个过程微软大大也是作出一定的努力,先点给赞先!就上述用一副图来看,估计会更加清晰明了吧

lambda表达式演变六部曲

1 4 收藏 评论

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部