在"委托、Lambda表达式、事件系列02,什么时候该用委托"一文中,使用委托让代码简洁了不少。

namespace ConsoleApplication2
{
    internal delegate bool MyCalculateDelegate(int val);
    class Program
    {
        static void Main(string[] args)
        {
            IEnumerable<int> source = new List<int>(){2, 3, 4, 5, 6, 7, 8, 9,10, 11};

            MyCalculateDelegate del = LessThanFive;
            var result = GetNumbers(source, del);
            foreach (int n in result)
            {
                Console.WriteLine(n);
            }
        }

        static IEnumerable<int> GetNumbers(IEnumerable<int> numbers, MyCalculateDelegate del)
        {
            foreach (int number in numbers)
            {
                if (del(number)) yield return number;
            }
        }

        static bool LessThanFive(int val)
        {
            return val < 5;
        }

        static bool LessThanTen(int val)
        {
            return val < 10;
        }
    }
}


可是,以上LessThanFive方法和LessThanTen方法的输入参数、输出类型、以及实现逻辑都是一致的,有没有一种形式可以替代它们?这正是Lambda表达式登场的时候!Lambda表达式是匿名委托,以=>分隔,左边是输入参数,右边是实现过程。

namespace ConsoleApplication2
{
    internal delegate bool MyCalculateDelegate(int val);
    class Program
    {
        static void Main(string[] args)
        {
            IEnumerable<int> source = new List<int>(){2, 3, 4, 5, 6, 7, 8, 9,10, 11};

            var result = GetNumbers(source, n => n < 5);
            foreach (int n in result)
            {
                Console.WriteLine(n);
            }
        }

        static IEnumerable<int> GetNumbers(IEnumerable<int> numbers, MyCalculateDelegate del)
        {
            foreach (int number in numbers)
            {
                if (del(number)) yield return number;
            }
        }

    }
}


以上,使用Lambda表达式又让代码简洁了不少!GetNumbers的实参n => n < 5,就是一个Lambda表达式,它符合委托MyCalculateDelegate的定义,输入参数是整型,输出是bool类型。

其实,lambda表达式n => n < 5是一种"语法糖",内部还是执行了如下代码:

        ......
        MyCalculateDelegate del = LessThanFive;
        var result = GetNumbers(source, del);
        ......
        static bool LessThanFive(int val)
        {
            return val < 5;
        }

这一点可以从IL层面看出。使用Reflector进行反编译:

private static void Main(string[] args)
{
    List<int> <>g__initLocal0 = new List<int>();
    <>g__initLocal0.Add(2);
    <>g__initLocal0.Add(3);
    <>g__initLocal0.Add(4);
    <>g__initLocal0.Add(5);
    <>g__initLocal0.Add(6);
    <>g__initLocal0.Add(7);
    <>g__initLocal0.Add(8);
    <>g__initLocal0.Add(9);
    <>g__initLocal0.Add(10);
    <>g__initLocal0.Add(11);
    IEnumerable<int> source = <>g__initLocal0;
    IEnumerable<int> result = GetNumbers(source, (CS$<>9__CachedAnonymousMethodDelegate2 != null) ? CS$<>9__CachedAnonymousMethodDelegate2 : (CS$<>9__CachedAnonymousMethodDelegate2 = new MyCalculateDelegate(Program.<Main>b__1)));
    foreach (int n in result)
    {
        Console.WriteLine(n);
    }
}

以上,由于n => n > 5符合委托MyCalculateDelegate的定义,在内部创建了一个MyCalculateDelegate类型的委托,然后把一个编译器生成的方法<Main>b__1赋给了委托变量。

[CompilerGenerated]
private static bool <Main>b__1(int n)
{
    return (n < 5);
}

<Main>b__1方法是由编译器帮我们自动生成的。

总结:lambda表达式其实是"语法糖",源代码被编译的时候,编译器会自动帮我们生成一个符合委托定义的方法,然后把该方法赋给委托。

“委托、Lambda表达式、事件系列”包括:

委托、Lambda表达式、事件系列01,委托是什么,委托的基本用法,委托的Method和Target属性

委托、Lambda表达式、事件系列02,什么时候该用委托

委托、Lambda表达式、事件系列03,从委托到Lamda表达式

委托、Lambda表达式、事件系列04,委托链是怎样形成的, 多播委托, 调用委托链方法,委托链异常处理

委托、Lambda表达式、事件系列05,Action委托与闭包

委托、Lambda表达式、事件系列06,使用Action实现观察者模式,体验委托和事件的区别

委托、Lambda表达式、事件系列07,使用EventHandler委托

委托、Lambda表达式、事件系列03,从委托到Lamda表达式的更多相关文章

  1. 委托、Lambda表达式、事件系列05,Action委托与闭包

    来看使用Action委托的一个实例: static void Main(string[] args) { int i = 0; Action a = () => i++; a(); a(); C ...

  2. 委托、Lambda表达式、事件系列07,使用EventHandler委托

    谈到事件注册,EventHandler是最常用的. EventHandler是一个委托,接收2个形参.sender是指事件的发起者,e代表事件参数. □ 使用EventHandler实现猜拳游戏 使用 ...

  3. 委托、Lambda表达式、事件系列06,使用Action实现观察者模式,体验委托和事件的区别

    在"实现观察者模式(Observer Pattern)的2种方式"中,曾经通过接口的方式.委托与事件的方式实现过观察者模式.本篇体验使用Action实现此模式,并从中体验委托与事件 ...

  4. 委托、Lambda表达式、事件系列04,委托链是怎样形成的, 多播委托, 调用委托链方法,委托链异常处理

    委托是多播委托,我们可以通过"+="把多个方法赋给委托变量,这样就形成了一个委托链.本篇的话题包括:委托链是怎样形成的,如何调用委托链方法,以及委托链异常处理. □ 调用返回类型为 ...

  5. 委托、Lambda表达式、事件系列02,什么时候该用委托

    假设要找出整型集合中小于5的数. static void Main(string[] args) { IEnumerable<int> source = new List<int&g ...

  6. 委托、Lambda表达式、事件系列01,委托是什么,委托的基本用法,委托的Method和Target属性

    委托是一个类. namespace ConsoleApplication1 { internal delegate void MyDelegate(int val); class Program { ...

  7. Lamda表达式的参数捕获,太酷了

    lamda表达式有了参数捕获这个功能,让Action这个委托变得无所不能.Action委托就是无参数,无返回值的一个代理类型. 它只能对应于下面这种类型的函数声明. public void Funct ...

  8. 委托-异步调用-泛型委托-匿名方法-Lambda表达式-事件【转】

    1. 委托 From: http://www.cnblogs.com/daxnet/archive/2008/11/08/1687014.html 类是对象的抽象,而委托则可以看成是函数的抽象.一个委 ...

  9. C# Note2:委托(delegate) & Lambda表达式 & 事件(event)

    前言 本文主要讲述委托和Lambda表达式的基础知识,以及如何通过Lambda表达式实现委托调用,并阐述.NET如何将委托用作实现事件的方式. 参考:C#高级编程 1.什么是委托(delegate)? ...

随机推荐

  1. linux:查询软件是否安装以及删除

    参考网址:http://blog.sina.com.cn/s/blog_6d59e57d0102x21u.html 查询java是否安装 rpm -qa |grep java 批量卸载所有带有Java ...

  2. 浅谈js设计模式之迭代器模式

    迭代器模式无非就是循环访问聚合对象中的各个元素.比如 jQuery中的 $.each 函数,其中回调函数中的参数 i 为当前索引, n 为当前元素,代码如下: $.each([1, 2, 3], fu ...

  3. c++中的类(class)

    c++的class(类)使用方法 这几天一直在调splay之类的东西,突然想转指针...qwq 于是,我就在沙华大佬的帮助下,学了下一顿乱指( $ -> $ ),也就是class(类) 首先:c ...

  4. Sublime Text 使用介绍/全套快捷键及插件推荐

    如果说Notepad++是一款不错Code神器,那么Sublime Text应当称得上是神器滴哥.Sublime Text最大的优点就是跨平台,Mac和Windows均可完美使用:其次是强大的插件支持 ...

  5. printf 字符串格式

    摘自:http://www.cppblog.com/API/archive/2013/07/18/201923.html 首先 long long是C99标准新规定的.不少编译器还不支持,Micros ...

  6. Net WebAPI2

    SwaggerUI ASP.Net WebAPI2   目前在用ASP.NET的 WebAPI2来做后台接口开发,在与前台做测试的时候,总是需要发送一个demo给他,但是这样很麻烦的,他还有可能记不住 ...

  7. 【Atcoder】ARC102 题解

    C - Triangular Relationship 题解 枚举一个数%K的值然后统计另两个 代码 #include <bits/stdc++.h> #define enter putc ...

  8. pageHelper 排序 +- 字符串处理

    自己记录一下. 前端要把sort参数传过来, 1. 如果约定是下面这种形式: sort=id-name+age+ 直接在java后台进行替换就行,连正则都不用. sort = sort.replace ...

  9. Hive项目开发环境搭建(Eclipse\MyEclipse + Maven)

    写在前面的话 可详细参考,一定得去看 HBase 开发环境搭建(Eclipse\MyEclipse + Maven) Zookeeper项目开发环境搭建(Eclipse\MyEclipse + Mav ...

  10. 数据库相关--mysql中的单表查询

    一.完整的单表查询语句 select [distinct] *|字段1,字段2, .... from 表名 [where 条件1] [group by 字段名 [having 条件2] ] [orde ...