委托、Lambda表达式、事件系列03,从委托到Lamda表达式_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 委托、Lambda表达式、事件系列03,从委托到Lamda表达式

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

 2014/10/1 18:01:56  Darren Ji  程序员俱乐部  我要评论(0)
  • 摘要:在"委托、Lambda表达式、事件系列02,什么时候该用委托"一文中,使用委托让代码简洁了不少。namespaceConsoleApplication2{internaldelegateboolMyCalculateDelegate(intval);classProgram{staticvoidMain(string[]args){IEnumerable<int>source=newList<int>(){2,3,4,5,6,7,8,9,10,11}
  • 标签:事件 Lambda表达式 AMD 表达式

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

monospace; width: 100%; margin: 0em; background-color: #f0f0f0">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表达式

上一篇: ASP.NET MVC 4.0 学习4-ActionResult 下一篇: 没有下一篇了!
发表评论
用户名: 匿名