C#中委托,匿名方法,Lambda表达式之间的关系

委托:就是一个类,通过IL中间语言编译器可以看到,就是一个class 的定义,无论它后面怎么变化,是 Delegate  自定义还是用内置委托  Action  Func  都是 一个类,

匿名方法:委托可以调用具体方法名作为参数,也可以直接在里面写方法体,这个方法体就是匿名方法,

匿名方法,直白点说,就是没有方法体的方法。

lambda表达式 就是一个方法,表面看是一个匿名方法,在IL里面你可以看到,他跟匿名方法又不一样,他会定义为一个普通方法。

 

 

都说C#是C语言版的Java,它是基于Java的基础上,增加的更多的独有的语言功能,而委托就是其中之一,而也就是委托让我感觉到从Java转到C#的一个大难点。
委托是通过delegate关键字来定义,简单来说,委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递。这方面就有些相似于JavaScript的函数,它也是能够将函数作为参数进行传递。至于为什么要这么做,其原理是观察者设计模式,这里我不做详细说明。
进入正题,首先我先给出这三者之间的从属关系:委托->匿名表达式->Lambda表达式。
从关系式不难看出,Lambda表达式一定能够转化成匿名表达式和原始的委托方式,而匿名表达式也一定能够转换成原始的委托方式。
 上代码:

        / //定义委托类型
        delegate int calculator(int x, int y);
        static void Main(string[] args)
        {
            //初始化委托类型(命名方法),注意是add不是add()
            calculator add1 = new calculator(add);
            //匿名方法是通过使用 delegate 关键字创建委托实例来声明的
            calculator add2 = delegate (int a, int b)
            {
                return a + b;
            };
            //任何 Lambda 表达式都可以转换为委托类型
            //表达式 lambda
            calculator add3 = (a, b) => a + b;
            //Func 类型:有任意返回值的委托类型,最后一个泛型是返回值类型
            Func<int, int, int> add4 = (a, b) => a + b;
            //给委托变量再绑定或者删除一个方法
            add1 += sub;
            //add1 -= sub;
            //add1()只会输出最近的那个函数的结果
            Console.WriteLine(add1(1, 6));
            Console.WriteLine(add2(2, 6));
            Console.WriteLine(add3(3, 6));
            Console.WriteLine(add4(4, 6));
        }
        private static int sub(int a, int b)
        {
            return 4 * a - b;
        }

        private static int add(int a, int b)
        {
            return 2 * a + b;
        }
 

 上述代码用4种方式实现一个加法功能:
第一种方式是最原始的委托使用方式,定义,声明,初始化,调用。
第二种方式是匿名方法的形式,通过delegate关键字将所需要绑定的方法直接内部实现。
第三种方式是 Lambda 表达式,进一步简化第二种方式的代码,变得更加简洁美观。
第四种方式是调用 .NET Core 框架内部已有的委托类型,此方式实现可重用。(推荐的使用方式)
由于委托的参数是方法,所以也可以将多个方法赋给同一个委托,当调用这个委托的时候,将依次调用其所绑定的方法。
在 .NET Core 框架内部定义的常用委托类型有两种:Action 类型与Func 类型。
它俩都是泛型类型,只不过前者是具有 void 返回类型的委托类型,而后者是有任意返回值的委托类型。
在C#中Lambda 表达式具体来说也有多种类型,上述代码的Lambda 表达式属于表达式 lambda,基础常用的还有语句Lambda和含标准查询运算符的 lambda。
上代码:


 int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
            //匿名方法
            int oddNumbers1 = numbers.Count(delegate (int n)
            {
                return n % 2 == 0;
            });
            Console.WriteLine(oddNumbers1);
            //含标准查询运算符的 lambda
            int oddNumbers2 = numbers.Count(n => n % 2 == 1);
            Console.WriteLine(oddNumbers2);
            //Action 类型:具有 void 返回类型的委托类型
            //匿名方法
            Action<int[], int, int> change1 = delegate (int[] nums, int a, int b)
              {
                  var tmp = nums[a];
                  nums[a] = nums[b];
                  nums[b] = tmp;
              };
            //语句Lambda
            Action<int[], int, int> change2 = (nums, a, b) =>
            {
                var tmp = nums[a];
                nums[a] = nums[b];
                nums[b] = tmp;
            };
            change1(numbers, 0, 1);
            change2(numbers, 2, 3);
            foreach (var item in numbers)
            {
                Console.Write(item + " ");
            }
 

 

 

 

 

相信经过上述两个案例的对比代码,这三者之间的关系应该就很容易理解了。
其实刚开始就想直接写出Lambda的确挺难的,还是先从委托开始慢慢过渡到熟悉匿名函数,最后就能轻易的掌握Lambda表达式!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值