一、什么是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 等。

Linq To Objects的更多相关文章

  1. Linq之旅:Linq入门详解(Linq to Objects)

    示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...

  2. [C#] Linq To Objects - 如何操作文件目录

    Linq To Objects - 如何操作文件目录 开篇语: 上次发布的 <LINQ:进阶 - LINQ 标准查询操作概述> 社会反响不错,但自己却始终觉得缺点什么!“纸上得来终觉浅,绝 ...

  3. [C#] Linq To Objects - 如何操作字符串

    Linq To Objects - 如何操作字符串 开篇语: 上次发布的 <LINQ:进阶 - LINQ 标准查询操作概述>(90+赞) 社会反响不错,但自己却始终觉得缺点什么!“纸上得来 ...

  4. LINQ to Entities 和LINQ to Objects 的区别

    本文资料来源:http://www.codeproject.com/Articles/246861/LINQ-to-Entities-Basic-Concepts-and-Features) LINQ ...

  5. Linq之Linq to Objects

    目录 写在前面 系列文章 linq to objects 总结 写在前面 上篇文章介绍了linq的延迟加载特性的相关内容,从这篇文章开始将陆续介绍linq to Objects,linq to xml ...

  6. 查询表达式和LINQ to Objects

    查询表达式实际上是由编译器“预处理”为“普通”的C#代码,接着以完全普通的方式进行编译.这种巧妙的发式将查询集合到了语言中,而无须把语义改得乱七八糟 LINQ的介绍 LINQ中的基础概念 降低两种数据 ...

  7. LINQ之LINQ to Objects(上)

    LINQ概述 LINQ,语言集成查询(Language Integrated Query),它允许使用C#或VB代码以查询数据库相同的方式来操作不同的数据源. 1.LINQ体系结构 从上图可以看出,L ...

  8. 从LINQ开始之LINQ to Objects(下)

    前言 上一篇<从LINQ开始之LINQ to Objects(上)>主要介绍了LINQ的体系结构.基本语法以及LINQ to Objects中标准查询操作符的使用方法. 本篇则主要讨论LI ...

  9. 从LINQ开始之LINQ to Objects(上)

    LINQ概述 LINQ,语言集成查询(Language Integrated Query),它允许使用C#或VB代码以查询数据库相同的方式来操作不同的数据源. LINQ体系结构 从上图可以看出,LIN ...

随机推荐

  1. HDU 1713 最小公倍数与最大公约数的问题 相遇周期

    欢迎参加——BestCoder周年纪念赛(高质量题目+多重奖励) 相遇周期 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/ ...

  2. SPFA算法心得

    SPFA算法是改进后的Bellman-Ford算法,只是速度更快,而且作为一个算法,它更容易理解和编写,甚至比Dijkstra和B-F更易读(当然,Floyd是另一回事了,再也没有比Floyd还好写的 ...

  3. 解决Centos关闭You have new mail in /var/spool/mail/root提示

    昨天搬到阿里云了. 装的系统是Centos 6.3的加固版 今天查看内存的时候 出现一天奇怪的提示 You have new mail in /var/spool/mail/root 有的时候每敲一下 ...

  4. 【python】捕获所有异常

    如下所示,在不知道异常名的情况下可以捕获所有异常 try: a=b b=c except Exception,ex: print Exception,":",ex

  5. 部署django应用

    Autor: wangxianlong 2016/7/10 16:17:55 环境: centos 6.5 python 2.7.5 django 1.9 nginx 1.8 selinux diab ...

  6. min-height在安卓下不起作用

    正常情况下,min-height可以当height使用 如: <div class="father"> <div class="child"& ...

  7. 虚拟机下安装ubuntu后root密码设置

    ctrl+alt+t:调出命令行. 问题描述: 在虚拟机下安装了ubuntu中要输入用户名,一般情况下大家都会输入一个自己的网名或绰号之类的,密码也在这时设置过了. 但是当安装成功之后,使用命令#su ...

  8. ASP.Net和新对象之context.Server

    描述 Server是一个HttpServerUtility类型的对象,不是一个类名 1.获取服务器上的绝对路径文件名tring ss = context.Server.MapPath("~/ ...

  9. zabbix_agent端 key

    root@(none):/etc/zabbix/zabbix_agentd.conf.d# grep -v "^$" /etc/zabbix/zabbix_agentd.conf| ...

  10. Ubuntu下中文显示乱码

    转自:http://jingyan.baidu.com/article/915fc414c9d2ef51384b204c.html 装好了Ubuntu 13.10 后,打开部分Windows下的txt ...