我们在 [.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 }
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);
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; });
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);
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 }
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中还会经常用到,让他在我们的应用和实践中慢慢深入他。