lambda
来源:互联网 发布:淘宝模特余露微博 编辑:程序博客网 时间:2024/05/16 08:45
:http://www.cnblogs.com/jordan51341
. 前言2. Lambda表达式概念
3. Lambda表达式树的概念和示例
4. Lambda表达式的简单应用
5. 总结
前言
在LINQ刚发布的时候,一直也没有时间去研究下LINQ,特别是在当时各种LINQ to ***纷纷出现,看得眼花缭乱。
在LINQ中增加的lambda表达式一直觉得挺神秘的,看到各位高手把lambda表达式运用得如火纯清,很是羡慕. 最近抽
空学习了解了下LINQ, 对学习的过程进行记录。文章基础,高手请飘过 :-)
计划学习的主要内容是lambda表达式,LINQ to Objects, LINQ to XML. 三个部分。
学习之前,推荐一款帮助学习LINQ的优秀工具LINQPad,下载地址:LINQPad下载 。
【另注:学习过程未免出现差错,欢迎指正】
Lambda表达式的概念
什么是lambda表达式?Lambda 表达式是一种匿名函数,它可以包含表达式和语句,并且可用于创建委托或
表达式目录树类型。我们使用lambda表达式可以帮助我们编写精简和紧凑的代码,许多操作中允许自定义排序和过
滤的函数,在.NET2.0的时候通常使用委托函数来实现,在.NET3.5可以使用lambda表达式。
现在举例说明lambda表达式: Func<int,int> addOne= item=> item+1,其中操作符 “=>”读作“Goes to”,
可以理解为操作符左边的是函数的参数,操作符右边是函数体内容。上面我们定义的lambda表达式等同于函数如下:
1 int addOne(int item)2 {3 return item+1;4 }
那么什么样的表达式才是合法的lambda表达式呢?
1. lambda表达式可以是多个参数。 如: (item1,item2)=>item1+item2;
2. lambda表达式可以是0个参数。 如: ()=>"csharp";
3. lambda表达式可以显示指定参数类型。 (int item1,string item2)=>item1+item2;
4. lambda表达式函数体可以使用多条语句. (item1)=>{string ret="hello"+item1;return ret;};
使用lambda表达式的时候,不得不提到泛型委托。在上面我们定义的表达式如:(item1,item2)=>item1+item2;
只是定义的表达式,我们如何调用呢?我们可以定义自己的函数委托来引用lambda表达式,如下
1 void Main()2 {3 Func<int,int> fun=(item1,item2)=>item1+item2;4 var result=fun(123,456);5 result.Dump("结果");6 }7 8 .结果9 579
关于Func<T>是泛型委托,最后的一个类型是指返回结果的类型,前面都是输入参数类型,上面的例子中,我们
的输入类型是INT,返回类型也是INT。同样如果我们定义Func<int,string,bool>,是指输入参数有两个,一个是int
类型,一个是string类型,函数返回是bool类型。使用泛型委托可以帮助我们方便引用lambda表达式。Func<T>提供
了多个重载,如下
1 void Main()2 {3 var c=n=>n+1;//Error,Cannot assign lambda expression to an implicitly-typed local variable4 Func<string> cc=>n+1;//Ok5 }
2. 在lambda表达式中可以直接访问本地变量和全局变量。
1 public delegate int RefParameterFunction(ref int n); 2 void Main() 3 { 4 int x=10; 5 RefParameterFunction fun= (ref int n)=> n++; 6 fun(ref x); 7 x.Dump(); 8 } 9 10 11 结果12 11
4. lambda表达式的参数可以支持不定参数数传入。
1 void Main() 2 { 3 4 Expression<Func<int,int>> tree = x=>x+1; 5 Func<int,int> exp= x=> x+1; 6 7 tree(1);//'tree' is a 'variable' but is used like a 'method' 8 exp(1);//输出2 9 }10 11
注意:tree只是lambada表达式的树形结构信息,并不是函数可以直接调用。
现在我们对lambda表达式的树结构输出来查看下,举例:我们编写一个验证三角形是否直角三角形,通过沟谷定律,
我们很容易编写lambda表达式为:
1 void Main()2 {3 Expression<Func<int,int,int,bool>> tree = (x,y,z)=>(x*x+y*y)==z*z;4 tree.Dump();5 }
输出结果如下:
通过输出的图形,我们可以清楚的看出整个lambda表达式是由LEFT和RIGHT两部分组成的,Left部分和right部分之间
的关系通过 NodeType属性指定,所有的NodeType类型通过枚举(System.Linq.Expressions.ExpressionType )定义,
而结点的Type可以看作返回类型,比如我们定义的 tree的Type是Func<int,int,int,bool>,而Type是Lambda。
那么如何把表达式树转换为可以直接使用的函数呢?Expression类提供了函数Compile(),就可以把我们定义的lambda
表达式树编译为实际的函数,代码如下:
1 ParameterExpression expX= Expression.Parameter(typeof(int),"x");2 ParameterExpression expY= Expression.Parameter(typeof(int),"y");3 ParameterExpression expZ= Expression.Parameter(typeof(int), "z");
接着我们使用二元表达式将参数表达式关联起来,X和X,Y和Y,Z和Z,二元关系都是乘.
1 BinaryExpression addXY = Expression.Add(mulX,mulY);
最后我们将X*X+Y*Y 和Z*Z通过 等于二元表达式关联起来.
1 void Main() 2 { 3 ParameterExpression expX= Expression.Parameter(typeof(int),"x"); 4 ParameterExpression expY= Expression.Parameter(typeof(int),"y"); 5 ParameterExpression expZ= Expression.Parameter(typeof(int), "z"); 6 BinaryExpression mulX= Expression.Multiply(expX, expX); 7 BinaryExpression mulY= Expression.Multiply(expY, expY); 8 BinaryExpression mulZ= Expression.Multiply(expZ, expZ); 9 BinaryExpression addXY = Expression.Add(mulX,mulY);10 BinaryExpression final= Expression.Equal(mulZ, addXY);11 Expression<Func<int, int, int, bool>> square = Expression.Lambda<Func<int, int, int, bool>>(final, expX, expY, expZ);12 Func<int, int, int, bool> xx= square.Compile();13 xx(3,4,5).Dump();14 }15 16 17 结果:18 True19
Lambda表达式的简单应用
1. 对数组的自定义排序。
1 void Main() 2 { 3 string[] items={"csharp","cpp","python","perl","java"}; 4 List<string> list=items.ToList(); 5 var result= list.FindAll(x=> x.Length==4); 6 7 result.Dump(); 8 } 9 10 结果:11 perl12 java
3. 对数组数据进行直接更新
总结
这篇学习记录对Lambda表达式和Lambda表达式树的最基础进行描述,对lambda没有更多深入的研究。比如在表达式树
的的动态修改,更多复杂的lambda表达式,lamdba表达式树对更复杂函数的构造。如果有兴趣,可以继续研究。
另:这是我发布的第一篇随笔,写一篇随笔原来也是挺艰难,水平有限,希望大家指正,谢谢。
- Lambda
- lambda
- lambda
- lambda
- Lambda
- lambda
- lambda
- Lambda
- Lambda
- lambda
- lambda
- lambda
- lambda
- lambda
- lambda
- lambda
- lambda
- lambda
- 支持向量机(SVM)基础
- Occupy FLB
- 康拓展开 & 逆康拓展开
- 函数重载的实现机制
- JAVA画SVG图(Batik框架)SVGComponentDemo
- lambda
- uilabel 和uitextview 自适应大小
- 第11周-项目2
- Android中Receiver处理机制禁忌小结
- request获取路径
- SQL 中 超简单的模拟split
- 如何关闭子进程
- poj3670,LiS(二分查找)
- 使用 /proc 文件系统来访问 Linux 内核的内容