Linq中存在大量的扩展方法。在System.Linq命名空间中,存在两个使用极其广泛的类Enumerable和Queryable,它们中就含有许许多多的扩展方法。扩展方法最重要的用途之一就是在Linq中的大量使用。本文将通过使用Enumerable中的一些扩展方法来完成一些简单的实例操作,进一步了解扩展方法在Linq中的使用。
1.准备工作
创建本例需要用到的学生类,该类仅包含学号,姓名,性别,年龄,成绩等属性。代码如下:
class Student { public int No { get; set; } public string Name { get; set; } public string Sex { get; set; } public int Age { get; set; } public float Score { get; set; } }
创建本例所需的学生实体集合,代码如下:
List<Student> stuList = new List<Student>(); stuList.Add(new Student { No = 1000, Name = "王欢", Sex = "女", Age = 20, Score = 50 }); stuList.Add(new Student { No = 1001, Name = "张燕", Sex = "女", Age = 18, Score = 89 }); stuList.Add(new Student { No = 1001, Name = "于强", Sex = "男", Age = 21, Score = 34 }); stuList.Add(new Student { No = 1001, Name = "刘海", Sex = "男", Age = 18, Score = 35 }); stuList.Add(new Student { No = 1001, Name = "李晗", Sex = "男", Age = 23, Score = 87 }); stuList.Add(new Student { No = 1001, Name = "吴萌", Sex = "女", Age = 18, Score = 76 }); stuList.Add(new Student { No = 1001, Name = "罗辉", Sex = "女", Age = 18, Score = 89 });
本例使用List<T>类来创建学生实体集合,该泛型类实现了接口IEnumerable<T>及IEnumerable,而“Enumerable 类提供了一组用于查询实现 IEnumerable<T> 的对象的 static(在 Visual Basic 中为 Shared)方法(msdn)”。所以本例中可以使用Enumerable 的扩展方法来对集合stuList进行相关操作。
2.用Where来筛选数据
要求:
筛选出年龄不小于20岁的学生信息,并将符合条件的学生的姓名及年龄信息输出界面。
实现:
var temp1=stuList.Where(it => it.Age >= 20); foreach (var t in temp1) { Console.WriteLine(t.Name+t.Age); }
运行结果:
说明:
在Visual studio中我们查看Where的定义,发现其定义位于Enumerable类中,所以本实例确实使用的是Enumerable类中的扩展方法。其函数签名如下:
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);
从函数签名可以看出:扩展方法Where从IEnumerable<TSource>类型的source中筛选出满足条件predicate的结果,返回值仍为IEnumerable<TSource>类型。
3.用Select进行投影操作
要求:
筛选出年龄不小于20岁的学生信息,并将符合条件的学生的姓名及年龄信息输出界面(同前)。
实现:
var temp2 = stuList.Where(it => it.Age >= 20) .Select(x => new {name=x.Name,age=x.Age }); foreach (var t in temp2) { Console.WriteLine(t); }
运行结果:
说明:
本例中使用Select方法后,产生了新的结果序列,该结果序列包含name及age两个字段。Where方法及Select方法的区别还是很明显的,Where方法根据条件对集合进行筛选操作,而Select方法对集合进行投影操作得到新的结果序列。
查看扩展方法Select的定义,得到其函数签名如下:
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector);
从函数签名中可以进一步了解到Select子句的作用:该扩展方法从集合source中按照selector指定的规则进行投影操作得到新的集合。
4.用OrderBy进行排序
要求:
筛选出年龄不小于20岁的学生信息,并将符合条件的学生的姓名及年龄信息输出界面(同前),同时按照姓名升序对结果进行排序。
实现:
var temp3 = stuList.Where(it => it.Age >= 20) .Select(x => new { name = x.Name, age = x.Age }) .OrderBy(y=>y.name); foreach (var t in temp3) { Console.WriteLine(t); }
运行结果:
说明:
在本例中,使用OrderBy方法进行排序,该方法的函数签名如下:
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);
通过前面例子的解析,详细这个函数前面大家可以看懂了吧。这里就不赘述了。
5.我们将方法链接在一起
通过前面三个例子的学习,我们发现:在Linq操作中,可以将各个单独的操作链接成一条管道,然后,信息在这条管道中传输。这其实是扩展方法存在的原因之一,因为扩展方法允许将静态方法的调用链接在一起。这样做的好处是能够以一种自然的方式将静态方法链接起来。
总结:通过实例学习了解了扩展方法在Linq中的使用。