Lambda表达式全面了解——通俗易懂

一、Lambda简介:

Lambda是一个表达式,也可以说它是一个匿名函数,然而在使用它或是阅读Lambda代码的时候,却显得并不那么容易,因为它匿名,删减了一些必要的说明信息(比如方法名)。所有的lambda表达式都是用新的lambda运算符 “ => ”,可以叫他,“转到”或者 “成为”。运算符将表达式分为两部分,左边指定输入参数,右边是为计算表达式

表达式:

               1.一个参数: param=>expo

               2.多个参数:(param-list)=>expo

 

优点:

  1. 在普通代码里几行的代码,在Lambda中只需要一行就可以解决。所以代码比以前更简洁了
  2. 可以在某一个方法内部定义,这样可以提高操作的便捷性

缺点:

  1. Lambda是一个匿名函数,因为是匿名,所以可读性变差了
  2. 有时候有多个Lambda嵌套(就像实例中的第3点一样),让程序变得难以理解

二、案例解析:细细研读

    public class Person
    {
        public string Name { get; set; }
        public int Age  {  get;set; }    //年龄
    }
    class Program
    {

        public static List<Person> PersonsList()
        {
            List<Person> persons = new List<Person>();
            for (int i = 0; i < 7; i++)
            {
                Person p = new Person() { Name = i + "儿子", Age = 8 - i, };//初始化7个对象
                persons.Add(p);                
            }
            return persons;
        }

        static void Main(string[] args)
        {
            List<Person> persons = PersonsList();
            persons = persons.Where(p => p.Age > 6).ToList();       //所有Age年龄>6岁 的Person的集合
            Person per = persons.SingleOrDefault(p => p.Age == 1);  //Age=1的单个people类
            persons = persons.Where(p => p.Name.Contains("儿子")).ToList();   //所有Name包含儿子的Person的集合
        }
    }

上面的代码很简洁,重点在最好三段代码用到Lambda表达式,下面我们来看下类似‘p=>p.Age>6’这样的表达式,到底是怎么回事?

首先我们先看明白‘委托’: 

        //委托  :超市
        delegate int Chaoshi(int a); 
        static void Main(string[] args)
        {
            Chaoshi gwl = JieZhang;  //结账委托给超市
            Console.WriteLine(gwl(10) + "");   //打印 显示 10
            Console.ReadKey();
        }
        
        //结账
        public static int JieZhang(int a)
        {
            return a;
        }

再看表达式:

 

 

 //委托  超市
        delegate int Chaoshi(int a);
        static void Main(string[] args)
        {          
            Chaoshi gwl = p => p ;// Chaoshi gwl = JieZhang;
            Console.WriteLine(gwl(10) + "");   //打印10,表达式的应用
            Console.ReadKey();
        }        
       // Chaoshi gwl = JieZhang;
            Console.WriteLine(gwl(10) + "");   //打印10,表达式的应用
            Console.ReadKey();
        }        
       

最后,通过委托和表达式的两段代码,我们可以大致看出:其实表达式(p => p;)中的 p 就代表委托方法中的参数‘a’,而表达式符号右边的 p,就是委托方法中的返回结果。

 

 

下面再上两个稍微复杂点的理解理解:

 

 

1.多参数的 :

 

 

//委托  超市
        delegate int Chaoshi(int a,int b);
        static void Main(string[] args)
        {            
            Chaoshi gwl = (p,z) => z-(p + 10);
            Console.WriteLine(gwl(10,100) + "");   //打印结果显示80(z对应参数b,p对应参数a)
            Console.ReadKey();
        }


 2. lambda主体运算复杂  

 

 

 

 

        /// 委托  超市
        /// <param name="a">花费</param>
        /// <param name="b">付钱</param>
        /// <returns>找零</returns>
        delegate int Chaoshi(int a,int b);
        static void Main(string[] args)
        {
            Chaoshi gwl = (p, z) =>
            {
                int zuidixiaofei = 10;
                if (p < zuidixiaofei)
                {
                    return 100;
                }
                else
                {
                    return z - p - 10;
                }
           
            };
            Console.WriteLine(gwl(10,100) + "");   //打印结果显示80(z对应参数b,p对应参数a)
            Console.ReadKey();
        }


下面介绍一个系统指定 Fun <T> 泛型委托的用法:多个参数,前面的为委托方法的参数,最后一个参数为委托方法的返回类型。

 

 

 

 

 static void Main(string[] args)
        {
            Func<int, string> gwl = p => p + 10 + "--string";            
            Console.WriteLine(gwl(10) + "");   //打印结果显示:‘20--string’
            Console.ReadKey();
        }

说明:我们可以看到,这里的p为int 类型参数, 然而lambda主体返回的是string类型的。

 

 

 

 

 

 

static void Main(string[] args)
        {
            Func<int, int, bool> gwl = (p, j) =>
                {
                    if (p + j == 10)
                    {
                        return true;
                    }
                    return false;
                };
            Console.WriteLine(gwl(5,5) + "");   //打印结果显示‘True’ 
            Console.ReadKey();
        }

说明:从这个例子,我们能看到,p为int类型,j为int类型,返回值为bool类型。

 

 

三、(放大招)动态创建Lambda表达式树:

 static void Main(string[] args)
 {
     //i*j+w*x
     ParameterExpression a = Expression.Parameter(typeof(int),"i");//创建一个表达式树中的参数,作为一个节点,这里是最下层的节点
     ParameterExpression b = Expression.Parameter(typeof(int),"j");
     BinaryExpression be = Expression.Multiply(a,b); //这里i*j,生成表达式树中的一个节点,比上面节点高一级

     ParameterExpression c = Expression.Parameter(typeof(int), "w");
     ParameterExpression d = Expression.Parameter(typeof(int), "x");
     BinaryExpression be1 = Expression.Multiply(c, d);

     BinaryExpression su = Expression.Add(be,be1);   //运算两个中级节点,产生终结点

     Expression<Func<int, int, int, int, int>> lambda = Expression.Lambda<Func<int, int, int, int, int>>(su,a,b,c,d);

     Console.WriteLine(lambda + "");   //打印结果:‘(i,j,w,x)=>((i*j)+(w*x))’

     Func<int, int, int, int, int> f= lambda.Compile();  //将表达式树描述的lambda表达式,编译为可执行代码,并生成该lambda表达式的委托;

     Console.WriteLine(f(1, 1, 1, 1) + "");  //打印结果:2
     Console.ReadKey();
 }


 
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值