Lambda 表达式是一种可用于创建 委托 或 表达式目录树 类型的匿名函数 。 通过使用 lambda 表达式,可以写入可作为参数传递或作为函数调用值返回的本地函数。 Lambda 表达式对于编写 LINQ 查询表达式特别有用。-MSDN

我们来看一下Lambda的进化:

  • 定义一个委托(C#1.0)
  • 实例化委托

    实例化委托需要传入一个方法,方法签名要和委托声明一致,需要我们在外部单独声明一个方法作为参数传入。

    缺点:需要单独声明方法,即使这个方法只用一次。

  • 匿名方法(C#2.0)

    匿名方法提供了一种传递代码块作为委托参数的技术,匿名方法是没有名称只有主体的方法。

    匿名方法中不需要指定返回类型,从方法体内的ruturn语句推断。

    匿名方法是通过使用delegate关键字创建委托实例来声明的,解决了每次都需要创建方法的问题。

    匿名方法还可以访问方法内的变量,如下面所示:

  • lambda表达式(C#3.0)

    到C#3.0,微软进行了大改革,把delegate关键字去掉,后面加上“=>”符号,就形成了lambda表达式。

    lambda表达式其实就是一个匿名方法,微软把delegate关键字去掉,一是写法上更简洁,二是提高编代码的效率(不需要去理解什么是delegate,和拖拉拽控件有异曲同工之妙)。

    此时已经挡不住微软的洪荒之力了,在此基础上又进行了简化(去掉参数类型)。

    你觉得到这里就该结束了,还是太年轻。

    搞了这么多,新手看老司机写的代码,保证一脸懵逼。以上各种变化有个优雅的名字:语法糖。

看完了我们自己定义的委托,我们来看看微软帮我们定义好的委托Action和Func

  • Action

  • Action<T>(泛型委托)


    微软为Action<T>最多提供了16个参数,统统没有返回值。
  • Func<T>(泛型委托)




    以此类推,微软为Func<T>提供了16个参数,前15个为输入参数,最后一个为输出参数。

委托也支持带ref out 关键字的参数

  • ref out参数

    Action 和 Func 无法完成,需要我们自定义委托。

匿名类

  • 匿名类(C#3.0)

    我们用ILSpy工具查看一下 截取其中一部分代码

    匿名类是一个密封类,而且属性全部只有get方法(只读),所以密封类不能修改属性的值(一旦声明,不可修改)。

扩展方法

  • 扩展方法(C#3.0)

    不要对object类型进行扩展,不然所有类都具有这个扩展方法。

    如果对某一类型增加扩展方法,恰好该类型也存在实例方法,此时程序会优先调用实例方法,找不到实例方法再去调用扩展方法。

    注意:如果对第三方类库进行扩展,一旦第三方类库更新恰好增加了一个和你扩展方法一样的实例方法,此时你的程序就会出现Bug,所以扩展方法虽好,不要乱用哦。

Linq

  • List.Where()方法 Lambda表达式写法

    现在我们看一下List中Where方法的构造

    首先是一个Linq的扩展方法,传入的参数是Func<TSource, bool> predicate,这是个什么东东,原来是微软定义好的一个委托Func,传入一个TSource类型,返回一个bool。

    下面我们来自己实现一下这个Where方法:

    WydWhere方法中source:listStudent。

  • Linq 标准查询表达式

    这就是语法糖。看到这,你会发现,是的,没错,只有你想不到,没有语法糖做不到。

如果转载,请给出原文链接,谢谢!


微信支付宝

如果本文帮助到您,请随意打赏作者