[.NET 3.x新特性三]Lambda表达式

时间:2023-01-01 18:59:44
    随着岁月的流逝,VS也从2005慢慢的步入2008,.NET也将进入3.5版本,学习的脚步也要慢慢赶上。今天我们来看看C#3.0的又一特性Lambda表达式,它由2.0代理演化而来,也是为LinQ做好必要的准备。 Lambda表达式首先我们要知道他的运算符“=>”,在我以前的一篇文章中可以得到在不同版本中所使用代理和通过Lambda表达式的一个例子,你可以在这里看到: [C#3.0]新特性概览 .今天我们举个另外的例子,让我们更好的理解这个Lambda表达式,因为我们在LinQ中会经常用到这个东东,所以就应该好好看看,况且这也不是什么难事。

    我们在
[.NET 3.x新特性一]自动属性,对象初始化及集合初始化 中讲到了自动化属性和集合的初始化,为了讲解Lambda表达式我们首先定义一个实体类,代码如下:

1       public   class  Person 
2      {
3           public   string  Name {  get set ; }
4           public   string  NickName {  get set ; }
5           public   int  Age {  get set ; }
6      }

    我们将其初始化一个List<Person>列表,并从中获取Age为23的Person实例和类表中所有实例中Age的平均值。当然其中也用到了扩展方法,这也是属于LinQ的一个范畴,代码如下:

1  List < Person >  people  =   new  List < Person >
2                                    {
3                                         new  Person{Name = " 小兵 " ,NickName = " 网魂小兵 " ,Age = 23 },
4                                         new  Person{Name = " 青青 " ,NickName = " QQing " ,Age = 22 }
5                                    };
6               // 取得people中Age为23的Person实例。
7              IEnumerable < Person >  results  =  people.Where(p  =>  p.Age  ==   23 );
8               // 计算people中的平均岁数。
9               int  perAge  =  people.Average(p  =>  p.Age);

    看到Lambda表达式了吗?p=>p这个就是Lambda表达式,当然Where和Average就是扩展方法,是LinQ的一个扩展方法。当然我们在C#或者说在.NET 2.0中也能够做到,但是可没有那么简单(其实也不难),下面我们看一下在.NET 2.0中的实现方法:

1              List < Person >  people  =   new  List < Person >
2                                    {
3                                         new  Person{Name = " 小兵 " ,NickName = " 网魂小兵 " ,Age = 23 },
4                                         new  Person{Name = " 青青 " ,NickName = " QQing " ,Age = 22 }
5                                    };
6 
7              IEnumerable < Person >  results  =  people.Where( delegate (Person p) {  return  p.Age  ==   23 ; });
8 
9               int  perAge  =  people.Sum( delegate (Person p) {  return  p.Age; });

    从上面我们也能够做到同样的效果,但是代码比用Lambda复杂了一点。下面我们看看这种代理方法的扩展是如何实现的呢?首先我们当然是右键选择"转到定义"就可以看到Where的扩展:

1 public   static  IEnumerable < TSource >  Where < TSource > (
2                    this  IEnumerable < TSource >  source, Func < TSource,  bool >  predicate);
3 public   static  IEnumerable < TSource >  Where < TSource > (
4                     this  IEnumerable < TSource >  source, Func < TSource,  int bool >  predicate);

    我们来看看Where的代码:

 1  public   static  IEnumerable < TSource >  Where < TSource > ( this  IEnumerable < TSource >  source,
 2   Func < TSource,  bool >  predicate) 
 3          {
 4               foreach  (TSource s  in  source) 
 5              {
 6                   if  (predicate(s)) 
 7                  {
 8                      yield  return  s;
 9                  }
10              }
11          }

    从上面的代码中我们可以看出是对IEnumerable<T>的扩展,而predicate是一个Func<T,bool>的代理,Func代理的第二个类型是返回的类型,而第一个类型是参数的类型。如果是Func<T,int,bool>则最后一个是代理返回的类型(就是这个代理方法执行后的结果),其他都是参数(代理方法的参数,依次排列),就上述代码而言predicate执行后返回true的就迭代返回实例s。

    OK今天就这样了,这个表达式在LinQ中还会经常用到,让他在我们的应用和实践中慢慢深入他。