zoukankan      html  css  js  c++  java
  • Linq To Objects

    一、什么是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:OrderingSystemBLLinDebugOrderingSystemBLL.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+": ==================================== ");
    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 等。

  • 相关阅读:
    转载 自定义ListView背景
    Android 在模拟器上创建sd卡
    转载 Android TextView加下划线
    转载 Dom4j生成xml
    转载 在Struts2中使用servlet 配置问题
    android开发不错的地方
    bat demo1自定义变量
    redhat 5下安装SVN
    linux 忘记root密码
    DEBUG Sigar no libsigarx86linux.so in java.library.path
  • 原文地址:https://www.cnblogs.com/CharlesGrant/p/3639981.html
Copyright © 2011-2022 走看看