lambda表达式详解

对于历来没接触过lambda表达式的人来讲,这个玩意很蛋疼,蛋疼的语法,蛋疼的外表,可是就和人同样,若是长得太突出(丑),通常就会有大才,毕竟老天是公平的嘛!函数

在具体分析lambda以前,先说两句:学习

1.lambda表达式不是必须的,由于其就是一个匿名函数,凡是经过lambda表达式能够完成的工做,均可以经过匿名函数来完成(固然,咱们也知道,匿名函数也不是必须的)。blog

2.lambda表达式能够极大简化咱们对匿名函数的使用.get

3.学习lambda表达式以前你最好对匿名函数、委托、泛型的概念有所了解。string

MSDN定义:Lambda 表达式是一种可用于建立委托表达式目录树类型的匿名函数it

经过上面的定义咱们能够了解:编译

1.lambda表达式是匿名函数,只不过长得不太像而已,能够当作是进化版。class

2.lambda表达式是用来建立委托或者目录树的匿名函数匿名函数

目录树是何许人也,放到其余章节说,这里只说lambda表达式建立委托。泛型

  首先,建立一个委托

delegate int del(int arg);

  而后建立一个符合这个委托定义的方法

static int Func1(int numb)
        {
            return numb + 10;
        }

  建立委托del的实例,这里建立委托的方法咱们用的是最基本的方法。

static void Main(string[] args)
        {
            del d1 = new del(Func1);
            Console.WriteLine(d1(10));
            Console.ReadKey();
        }

  好,上面咱们建立了委托del的实例。

咱们知道若是一个方法可能只用一次,咱们就不必单首创建这个方法,而是可使用匿名函数。那么咱们假设Func就是那个只使用一次的函数,咱们能够将上面的建立委托的实例的代码改成使用匿名函数的版本。

 static void Main(string[] args)
        {
            del d1 = delegate(int numb)
            {
                return numb + 10;
            };
            Console.WriteLine(d1(10));
            Console.ReadKey();
        }

  分析一下这个匿名函数:delegaet关键字、匿名函数的参数的类型和形参名称、函数体,还能不能更简单一点呢?继续看,主角来了

 static void Main(string[] args)
        {
            del d1 = p => p + 10;
            Console.WriteLine(d1(10));
            Console.ReadKey();
        }

  p=>p+10就是lambda表达式,咱们来分析一下,很简单的哟

1.=>读做“成为”、"转成",英文读做"goes to"

2.=>左边的p表示调用方法时给方法传入的参数

3.=>右边的p+10,表示方法体

对比上面使用匿名函数建立委托实例,左边的p就至关于 numb,右边的p+10就至关于{return p+10;}

咱们能够乐观的认为,lambda表达式在编译阶段仍然转换成了对应的匿名函数,别问我怎么知道,我猜的!

画张图表示一下。

因此咱们前面说过,lambda表达式也是匿名函数,只不过简化了匿名函数的使用。

因此咱们前面也说,lambda表达式是用来建立委托的,你看咱们刚才不就是再建立委托的实例吗?!

因此到如今为止,你应该记住一句话:lamb表达式没什么特殊之处,只不过是C#的一种语言特性而已,或者说一种语法而已。

道理明白了,下面咱们来稍微增强一点。

定义一个两个参数的委托

delegate int del(int arg1,int arg2);

  本身试试,首先使用匿名函数的方式建立这个委托的一个实例,而后再使用lambda表达式看看。

  使用匿名函数

del d1 = delegate(int numb1, int numb2)
            {
                return numb1 + numb2;
            };
            Console.WriteLine(d1(10,10));
            Console.ReadKey();

  使用lambda表达式

 del d1 = (p, z) => p + z;
            Console.WriteLine(d1(10,10));
            Console.ReadKey();

  没错,两个参数的时候就是使用括号括起来,用都好分割两个参数,这里p就表示numb1,z就表示numb2。

咱们稍微弄个复杂点的:定义一个购物的委托

/// <summary>
        /// 定义一个购物的委托,分别接受两个参数
        /// </summary>
        /// <param name="spend">实际消费金额</param>
        /// <param name="cash">付给商家的金额</param>
        /// <returns>商家找回的金额</returns>
        delegate double ShoppingDelegate(double spend, double cash);

  使用匿名方法的方式建立这个委托的实例,方法的逻辑稍微复杂点

ShoppingDelegate d1 = delegate(double spend, double cash)
            {
                /*变量card表示会员卡上的金额,咱们都有经验,若是常常会将几毛钱存入会员卡,方便下次使用,这样能够少带零钱。若是会员卡的金额>0.5,则将会使用会员卡上的金额;不然不适用*/
                double card = 0.5;
                if (card > 3)
                {
                    return cash - spend + card;
                }
                else 
                {
                    return cash - spend;
                }
            };

  这样该如何改为lambda表达式呢?没错,若是代码比较多的话,lambda表达式也使用{}。

ShoppingDelegate d1 = (p,z)=>
            {
                /*变量card表示会员卡上的金额,咱们都有经验,若是常常会将几毛钱存入会员卡,方便下次使用,这样能够少带零钱。若是会员卡的金额>0.5,则将会使用会员卡上的金额;不然不适用*/
                double card = 0.5;
                if (card > 3)
                {
                    return z - p + card;
                }
                else 
                {
                    return z - p;
                }
            };

  有人会问,为何lambda表达式中的参数p和z不用spend和cash表示呢?固然能够了,只不过lambda表达式比较叼,能用一个字符表示的,绝对不使用一个半。

好,这一节就到这里,下一节专门说说lambda表达式和linq的配合使用。

相关文章
相关标签/搜索