Linq系列:基础与本质(Part III)

-

前面我们对LINQ的本质,以及MS针对LINQ对3.5新增的几个类做了分析。作为本系列的第一篇:基础与本质的最后一篇,我想对Lambda表达式讲解一下。本来Lambda表达式也可以放到系列c#3.x学习中,我想还是放到LINQ系列比较好讲一些。

1 Lambda表达式例子

先来熟悉一下Lambda的一般样子,代码:

 1 x => x * 2;
 2 (x, y) => x * 10 + y;
 3 (x, y, z) => (1 / x + 10) * y + z;
 4 Func<int, int> f1;
 5 f1 = x => x * 2
 6 Func<int, int, int> f2;
 7 f2 = (x, y) => x * 10 + y; 
 8 Func<int, int, int, int> f3;
 9 f3 = (x, y, z) => (1 / x + 10) * y + z;
10 // A lambda expression with no arguments
11 Func<int> f4 = ()=> 10;
12 int r1 = f1(10);
13 int r2 = f2(5, 10);

这些是C#3.0新特性为Lambda定义的格式。

Func<int, int> f1 = x => x * 2;<=> Func<int, int> f1 = delegate(int x){return x * 2;};

我们说这两种方式可以说在某种情况下是等价的,为什么等价的呢?请看本文的第二部分的分析

2 Lambda 表达本质

Lambda 表达式可以用在任何需要使用匿名方法,或是代理的地方。我们看看下面的代码:

1 List<int> numbers = new List<int>102028401358 };
2 List<int> evenNumbers = numbers.FindAll( i => ( i % 2 ) == 0 );
3 List<int> evenNumbers1 = numbers.FindAll( delegate(  int i )
4 {
5   return ( i % 2 ) == 0;
6  } );

我们通过Reflector工具可以看到编译器会将Lambda表达式编译为标准的匿名方法。下面是在Reflector下看到的代码:

1  List<int> evenNumbers = numbers.FindAll(delegate (int i) {
2          return (i % 2== 0;
3      });
4  List<int> evenNumbers1 = numbers.FindAll(delegate (int i) {
5          return (i % 2== 0;
6      });

现在看看他们的IL:

 1 L_0060: ldftn bool LINQProject.test2::<TestLambda>b__1(int32)
 2 L_0066: newobj instance void [mscorlib]System.Predicate`1<int32>::.ctor(object, native int)
 3 L_006b: stsfld class [mscorlib]System.Predicate`1<int32> LINQProject.test2::CS$<>9__CachedAnonymousMethodDelegate3
 4 L_0070: br.s L_0072
 5 L_0072: ldsfld class [mscorlib]System.Predicate`1<int32> LINQProject.test2::CS$<>9__CachedAnonymousMethodDelegate3
 6 L_0077: callvirt instance class [mscorlib]System.Collections.Generic.List`1<!0> [mscorlib]System.Collections.Generic.List`1<int32>::FindAll(class [mscorlib]System.Predicate`1<!0>)
 7 L_007c: stloc.1 
 8 L_007d: ldloc.0 
 9 L_007e: ldsfld class [mscorlib]System.Predicate`1<int32> LINQProject.test2::CS$<>9__CachedAnonymousMethodDelegate4
10 L_0083: brtrue.s L_0098
11 L_0085: ldnull 
12 L_0086: ldftn bool LINQProject.test2::<TestLambda>b__2(int32)
13 L_008c: newobj instance void [mscorlib]System.Predicate`1<int32>::.ctor(object, native int)
14 L_0091: stsfld class [mscorlib]System.Predicate`1<int32> LINQProject.test2::CS$<>9__CachedAnonymousMethodDelegate4
15 L_0096: br.s L_0098
16 L_0098: ldsfld class [mscorlib]System.Predicate`1<int32> LINQProject.test2::CS$<>9__CachedAnonymousMethodDelegate4
17 L_009d: callvirt instance class [mscorlib]System.Collections.Generic.List`1<!0> [mscorlib]System.Collections.Generic.List`1<int32>::FindAll(class [mscorlib]System.Predicate`1<!0>)
18 L_00a2: stloc.2

 

通过对Lambda表达式的IL的分析是编译器自动生成相应的静态成员和静态方法,带来着一些的都是编译器,CLR并没有做出实质的改变,这就更加验证了上一篇文章的说明,委托,匿名方法,Lambda表达式都是一脉相承的,实现原理都是通过委托。

3 Lambda表达式的分析

MS定义Lambda表达式的标准写法为:

ArgumentsToProcess => StatementsToProcess

被编译器编译为:

inputs (delegate parameters) =>Expression to be evaluated(expression return must match delegate return value type)

其中=>为Lambda的操作符。

比如前面的代码:List<int> evenNumbers = numbers.FindAll( i => ( i % 2 ) == 0 );我们可以理解为:List<int> evenNumbers = numbers.FindAll( (i) => (( i % 2 ) == 0 ));我们也可以现实的指示输入参数的类型。当有有多行处理表达式时,需要使用大括号包起来,例如:

Code

当输入参数有多个时:

Code

当没有参数的时候:()里面可以为空。

局部变量也可以在Lambda表达式中使用,例如

Code

 

最后希望大家对CLR系列和LINQ系列提出宝贵的建议以及希望增加对什么知识点的讲解。谢谢!

待续。。。

版权所有归"布衣软件工作者".未经容许不得转载.

posted on 2008-11-21 18:05 gjcn 阅读(1542) 评论(7)  编辑 收藏 网摘 所属分类: LINQ

评论

#1楼 2008-11-21 10:33 simon_cm[未注册用户]

学习中..   回复  引用    

#2楼 2008-11-21 10:36 hahahehe[未注册用户]

又一篇,看看。   回复  引用    

#3楼 2008-11-21 10:49 紫色永恒      

呵呵 等来了   回复  引用  查看    

#4楼[楼主] 2008-11-21 11:25 gjcn      

@紫色永恒
多谢支持,后续会及时更新的。
  回复  引用  查看    

#5楼 2008-11-21 11:30 longlongage[未注册用户]

很好很直观,楼主是我的偶像   回复  引用    

#6楼[楼主] 2008-11-21 11:39 gjcn      

@longlongage
多谢
  回复  引用  查看    

#7楼 2008-11-24 11:14 很爽[未注册用户]

楼主的文章,我一气看完,感觉把比较复杂深入的东西,讲的很有条理啊!!是学习的好文章!!!顶起!!!!!!!!!!!!!   回复  引用    

发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1336047




相关文章:

相关链接:

导航

公告

These postings are provided "AS IS" with no warranties, and confer no rights.
想回家了,想辞职了,但是眼下的经济形式,想做到不容易啊
<2008年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

统计

与我联系

搜索

 

常用链接

留言簿

我参与的团队

随笔分类

随笔档案

文章分类

友情BLOG

最新评论

阅读排行榜

评论排行榜