一、什么是Linq To Objects

从根本上说,Linq To Objects表示一种新的处理集合的方法。采用旧方法,必须编写指定如何从集合检索数据的复杂的foreach循环。而采用Linq方法,只需要编写描述要检索的内容的声明性代码。

二、使用Linq To Objects的优势

与传统的foreach循环相比,Linq查询具有三大优势:

  • 更简明、更易读、尤其是在筛选多个条件时。
  • 使用最少的应用程序代码提供强大的筛选、排序和分组功能。
  • 无需修改或只需很小的修改即可将它们移植到其他数据源。

通常,对数据执行的操作越复杂,使用Linq代替传统迭代技术的好处就越多。

三、Linq To Objects技术的介绍和演示

1、Linq和字符串

Linq可用于查询和转换字符串和字符串集合。它对文本文件中的半结构化数据尤其有用。Linq查询可与传统的字符串函数和正则表达式结合使用。


 1 ///<summary>
2 /// 查询指定字符串在文章中出现的次数
3 ///</summary>
4 publicstaticvoid GetStringCount()
5 {
6 //数据源
7 string article =
@"The Endorsed Standards for Java SE constitute all classes and "+
8 @" interfaces that are defined in the packages listed in this section. "+
9 @"Classes and interfaces defined in sub-packages of listed packages"+
10 @" are not Endorsed Standards unless those sub-packages are themselves listed."+
11 @" The Endorsed Standards Override Mechanism may be used to override the Java SE"+
12 @" platform packages in this list, and these packages may be"+
13 @" overridden only by versions of the Endorsed Standard that"+
14 @"are newer than that provided by the Java platform as released by Sun."+
15 @" With the exception of packages listed here and the technologies "+
16 @"listed in the Standalone Technologies section below, no other "+
17 @" packages from the Java SE platform API specification may be overridden.";
18
19 //根据字符数组中匹配的符号,分割字符串得到一个存放单词的字符串数组
20 string[] words = article.Split(newchar[] { '.', '' });
21
22 //把单词数组中packages查询出来
23 var query = from word in words
24 where word =="packages"
25 select word;
26
27 //输出文章中一共有多少个packages
28
29 Console.WriteLine("packages出现过{0}次", query.Count());
30 Console.Read();
31 }

需求:从这段文字节选中查找"packages"出现的次数

分析:先用字符串示例方法split(char[] arr)方法,将字符串转换成单词数组,然后使用Linq查询,遍历单词数组中的每个单词,筛选出所有的"packages",然后调用Count()方法统计出有多少个"packages"。


 1 ///<summary>
2 /// 获取字符串中的数字
3 ///</summary>
4 publicstaticvoid GetDigitFromString()
5 {
6 //字符串数据源
7 string strr ="sdfsdf232sd09sdfds";
8
9 //查询字符串中是数字的查询语句
10 var query = from ch in strr
11 where Char.IsDigit(ch)
12 select ch;
13
14 //执行查询并输出结果
15 foreach (var ch in query)
16 {
17 Console.WriteLine(ch+",");
18 }
19
20 Console.Read();
21 }

需求:获取字符串中的数字

分析:使用Linq遍历字符串中每个字母(字符串类型已经实现了IEnumerable接口,所以可以使用Linq查询),然后调用Char类的静态方法IsDigit(char c)进行筛选,筛选出数字返回。

2、Linq和反射

.NET Framework类库反射API可用于检查.NET程序集中的元数据,及创建位于该程序集中的类型、类型成员、参数等等的集合,因为这些集合支持泛型IEnumerable(T)接口,所以可以使用Linq查询它们。


 1 ///<summary>
2 /// Linq To Reflection测试方法
3 ///</summary>
4 publicstaticvoid TestReflection()
5 {
6 //程序集的文件路径
7 string file =
8 @"G:\OrderingSystemBLL\bin\Debug\OrderingSystemBLL.dll";
9
10 //加载该程序集
11 Assembly assembly = Assembly.LoadFrom(file);
12
13 //查询程序集中所有的公共类中的公共方法,根据类来分组的查询语句
14 var query = from type in assembly.GetTypes()
15 where type.IsPublic
16 from method in type.GetMethods()
17 where method.IsPublic
18 group method by type;
19
20 //执行查询并输出结果
21 foreach (var methods in query)
22 {
23 Console.WriteLine(methods.Key+":\n====================================\n");
24 foreach (var method in methods)
25 {
26 Console.WriteLine(method.ToString());
27 }
28 }
29
30 Console.Read();
31 }

需求:将OrderingSystemBLL.dll程序集中所有公共类中的公共方法输出到控制台

分析:首先找到OrderingSystemBLL.dll程序集,并加载该程序集,然后通过Linq查询便利程序集中每个元素,筛选出是用Public修饰的类,然后再遍历这些类中的每个方法,筛选出是Public修饰的,并且以类型分组返回。

3、Linq和文件目录

许多文件系统操作实质上是查询,因此非常适合使用Linq方法。


 1 ///<summary>
2  /// Linq to FileInfo测试方法
3  ///</summary>
4  publicstaticvoid TestLinqToFileInfo()
5 {
6 //指定路径
7  string path =@"G:\MyOffice";
8
9 //获取该路径的所有文件信息,作为数据源
10   IEnumerable<System.IO.FileInfo> files = GetFiles(path);
11
12 //查询该文件信息集合中最近创建的后缀名为.aspx的文件
13   var query = (from file in files
14 where file.Extension ==".aspx"
15 orderby file.CreationTime descending
16 select file).First();
17
18 //输出结果
19   Console.WriteLine(query.Name + ":" + query.CreationTime);
20
21 Console.Read();
22 }
23
24  ///<summary>
25  /// 获取指定路径的所有文件信息
26  ///</summary>
27  ///<param name="path">指定路径</param>
28  ///<returns>指定路径的所有文件信息</returns>
29  publicstatic IEnumerable<System.IO.FileInfo> GetFiles(string path)
30 {
31 //如果不存在该路径,提示用户该路径不存在
32  if (!System.IO.Directory.Exists(path))
33 {
34 Console.WriteLine("该路径不存在!");
35 }
36
37 //定义一个存放文件名信息的数字
38  string[] fileNames =null;
39
40 //定义一个存放文件信息的集合
41   IList<System.IO.FileInfo> fileInfoList =new List<System.IO.FileInfo>();
42
43 //根据路径和查询条件在所有的子目录下获得文件名
44   fileNames = System.IO.Directory.GetFiles(path, "*.*",
45 System.IO.SearchOption.AllDirectories);
46
47 //循环遍历,将文件信息添加到集合中
48  foreach (var fileName in fileNames)
49 {
50 fileInfoList.Add(new System.IO.FileInfo(fileName));
51 }
52
53 return fileInfoList;
54 }

需求:查询出指定文件目录下,最近被修改过的后缀名为".aspx"的文件打印到控制台

分析:使用GetFiles方法将指定目录下的所以的文件目录和文件加载,遍历文件信息集合中每个文件信息,筛选出后缀名为".aspx"的文件信息,并且根据创建时间进行倒序排序,取第一个返回。

4、Linq和ArrayList

在使用Linq查询非泛型IEnumerable集合(如:ArrayList)时,必须显示声明范围变量的类型以反映此集合中对象的特定类型。


 1 ///<summary>
2 /// Linq To ArrayList测试方法
3 ///</summary>
4 publicstaticvoid TestLinqToArrayList()
5 {
6 //数据源为ArrayList
7 ArrayList studentList =new ArrayList
8 {
9 new Student
10 {
11 ID =1,
12 Name ="Jackie",
13 Scores =newint[]{92,82,88,72}
14 },
15
16 new Student
17 {
18 ID =2,
19 Name ="Kevin",
20 Scores =newint[]{90,82,68,72}
21 },
22
23 new Student
24 {
25 ID =3,
26 Name ="Helen",
27 Scores =newint[]{82,82,88,72}
28 },
29
30 new Student
31 {
32 ID =4,
33 Name ="Jim",
34 Scores =newint[]{78,82,83,72}
35 }
36 };
37
38 //查询第一门课程成绩90分以上的学生
39 var query = from Student stu in studentList
40 where stu.Scores[0] >90
41 select stu;
42
43 //执行查询并输出结果
44 foreach (var stu in query)
45 {
46 Console.WriteLine(stu.Name);
47 }
48
49 Console.Read();
50 }

需求:查询ArrayList集合中第一门成绩90分以上的学生

分析:遍历ArrayList集合中每个学生(注意ArrayList是个非泛型集合,因此这里的范围类型stu的类型必须显示声明为Student),筛选出第一门成绩大于90的学生对象返回。

四、查询操作中的类型关系

  • Linq查询操作在数据源、查询本身及查询执行中是强类型的。
  • 查询中变量的类型必须与数据源中元素的类型和foreach语句中迭代变量的类型兼容
  • 此强类型保证在编译时捕获类型错误,以便可以在用户遇到这些错误之前更正它们。

1、不转换源数据的查询

  • 数据源的类型参数决定范围变量的类型。
  • 选择的对象的类型决定查询变量的类型,此处的name为一个字符串。因此,查询变量是一个IEnumerable<string>。
  • 在foreach语句中循环访问查询变量。因为查询变量是一个字符串序列,所以迭代变量也是一个字符串。

2、转换源数据的查询

  • 数据源的类型参数决定范围变量的类型。
  • select语句返回Name属性,而非完整的Customer对象。因为Name是一个字符串,所以custNameQuery的类型参数是string而非Customer.
  • 因为custNameQuery是一个字符串序列,所以foreach循环的迭代变量也必须是string。

3、编译器推断类型的查询

  • 数据源的类型参数始终为查询中的范围变量的类型。
  • 因为select语句生成匿名类型,所以必须使用var隐式类型化查询变量。
  • 因为查询变量的类型是隐式的,所以foreach循环中的迭代变量也必须是隐式的。

五、查询语法和方法语法

通过使用C# 3.0 中引入的声明性查询语法,介绍性LINQ 文档中的多数查询都被编写为查询表达式。但是,.NET 公共语言运行库 (CLR)本身并不具有查询语法的概念。因此,在编译时,查询表达转换为CLR 确实了解的内容:方法调用。这些方法称为“标准查询运算符”,它们具有如下名称:Where、Select、GroupBy、Join、Max、Average 等。

最新文章

  1. webstorm--破解
  2. Spring Boot项目的打包和部署
  3. js之滚动置顶效果
  4. js根据生日计算出年龄
  5. 彻底掌握this,call,apply
  6. Jsonp简单认识(后端使用的是asp.net mvc)
  7. ****CSS各种居中方法
  8. WKWebView新特性及JS交互
  9. Hive分布式的数据仓库
  10. JQ笔记
  11. shell脚本中局部变量local
  12. ZooKeeper介绍,安装,配置文件解析
  13. oracle 查看表空间,及大小,利用率
  14. win7(windows 7)系统下安装SQL2005(SQL Server 2005)图文教程
  15. 腾讯视频国际版(Android)电量测试方法研究与总结
  16. Smobiler Service是什么?(Smobiler——.NET移动开发平台)
  17. LR IP欺骗
  18. 剑指Offer 42. 和为S的两个数字 (其他)
  19. Day 8 集合与文件的操作
  20. poj-2096-期望/dp

热门文章

  1. FastJSON 简介及其Map/JSON/String 互转
  2. java笔试三
  3. Python fopen,open,和popen的区别
  4. 基本二叉搜索树的第K小元素
  5. Django之表单字段的选填与后台界面的管理
  6. HybridApp iOS ATS解决方案
  7. 类似于fopen与fopen64的种种情况
  8. CentOS下配置Hadoop集群:java.net.NoRouteToHostException: No route to host问题的解决
  9. Android UI组件
  10. Set和Map