大学IT网 - 最懂大学生的IT学习网站! QQ资料交流群:367606806
当前位置:大学IT网 > C#技巧 > 委托、Lambda表达式、事件系列03,从委托到Lamda表达式

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

关键词:委托Lambda表达式事件  阅读(563) 赞(14)

[摘要]本文是对委托、Lambda表达式、事件系列03,从委托到Lamda表达式的讲解,对学习C#编程技术有所帮助,与大家分享。

在"委托、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;

        }


看出。使用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表达式其实是"语法糖",源代码被编译的时候,编译器会自动帮我们生成一个符合委托定义的方法,然后把该方法赋给委托。



相关评论