lambda

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 variable 4   Func < string > cc => n + 1 ; // Ok 5   }

 

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 True 19  
复制代码

 

 

 

 

 

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 perl 12 java
复制代码

 

 

3. 对数组数据进行直接更新

 

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

 

 

 

 

 

总结

 

这篇学习记录对Lambda表达式和Lambda表达式树的最基础进行描述,对lambda没有更多深入的研究。比如在表达式树

的的动态修改,更多复杂的lambda表达式,lamdba表达式树对更复杂函数的构造。如果有兴趣,可以继续研究。

另:这是我发布的第一篇随笔,写一篇随笔原来也是挺艰难,水平有限,希望大家指正,谢谢。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值