一、标准查询运算符

1、C#提供了标准查询运算符,例如我想选择专利一系列(pantents)中以年份19开头的专利,可以用如下语句:

            IEnumerable<Patent>  pantentWhere = pantents.Where(pantent =>
pantent.YearOfPublicaton.StartsWith(""));

当然,此处的语句只是定义了查询,此时pantentWhere并没有内容,后面Lambda表达式指定的查询并没有执行,只有当遍历pantentWhere集合的时候才开始执行这个查询规则,这是C#中标准查询的“推迟执行”

2、投射

专利类包含了 名字  年份  应用号  发明者 等,如果我想将专利类的集合中 每个专利的类型都变为只包含 名字与年份的类型,那么可以使用select做到,代码如下:

 var pantentSelect = pantents.Select(
pantent =>
{
return new
{
Title = pantent.Title,
Year = pantent.YearOfPublicaton
};
});

可以看到,Lambda表达式返回了一个包含 名字与年份的类型。而当遍历pantentSelect时,其投射语句执行,它则是有[(姓名,值),(年份,值)]构成的集合。

3、排序

利用标准查询运算符OrderByDescending 与 ThenByDescending 可以完成多条件的排序,代码如下:

 IEnumerable<Patent> pantentOrder = pantents.OrderByDescending(pantent =>
pantent.YearOfPublicaton).ThenByDescending(
pantent => pantent.Title);

可以看到,只用了一个OrderBy,它会获取并且只会获取一个成为KeySelector的参数来排序,例如本例中的YearOfPublicaton。如果要继续按照第二个关键字排序,只能用ThenBy,在OrderBy的基础上执行。而连着使用多个OrderBy只会撤销上一个OrderBy,所以要用ThenBy,而不是继续使用OrderBy。

此处仅仅简单的列出几项,因为如果执行比较复杂的查询与投射,将会产生比较繁琐难懂的代码。因此,C# 3.0中引入了标准查询表达式,一种更类似于SQL语言的

二、标准查询表达式

1、简单示例,下段代码完成的功能是检索出不含有*的单词:

 class Program
{
static string[] Keywords = { "*a", "*b", "*c", "*d", "*e", "*f", "a", "b", "c", "d", "e", "f", "g", "h", "i"};
static void Main(string[] args)
{
ShowContextualKeyword1();
}
public static void ShowContextualKeyword1()
{
IEnumerable<string> selection = from word in Keywords
where !word.Contains('*')
select word;
foreach (string s in selection)
{
Console.WriteLine(" " + s);
}
}
}

值得详细说一下的是类型推断:select投射回的是word的集合,word的类型是from后面的那个word,从Keywords推断得到。Keywords是一个string的集合,所以word是string类型,因此select投射到的是IEnumerable<string>

2、改变返回类型。

select不仅可以返回原始类型,也可以返回指定的类型,我个人总结的是 他会返回select后面的变量的集合类型。

如下代码,返回的不是fileName的集合,而是FileInfo的集合:

   public static void List1(string rootDirectory, string searchPattern)
{
IEnumerable<FileInfo> files = from fileName in Directory.GetFiles(rootDirectory, searchPattern)
select new FileInfo(fileName);
foreach (FileInfo file in files)
{
Console.WriteLine(".{0}({1})",file.Name,file.LastWriteTime);
}
}

当然,3.0允许程序员不必显示声明投射的类型,而可以使用匿名类型,如下代码所示:

 public static void List2(string rootDirectory, string searchPattern)
{
var files = from fileName in Directory.GetFiles(rootDirectory, searchPattern)
select new
{
Name = fileName,
LastWriteTime = File.GetLastWriteTime(fileName)
};
foreach (var file in files)
{
Console.WriteLine(".{0}({1})", file.Name, file.LastWriteTime);
}
}

如果select的原始数据的列特别多,改变投射类型则显得十分有优势,只需选出需要关注的几列即可,而不用全部都检索出来。

3、筛选(where)

筛选条件靠断言来表示,即返回布尔值的一个,真就接受,假就放弃。代码如下,功能是筛选出一个月之前修改的文件:

  static void FindMonthOldFiles(string rootDirectory, string searchPattern)
{
// 筛选出一个月之前访问的数据
IEnumerable<FileInfo> files = from fileName in Directory.GetFiles(rootDirectory, searchPattern)
where File.GetLastWriteTime(fileName) < DateTime.Now.AddMonths(-)
select new FileInfo(fileName);
foreach (FileInfo file in files)
{
string relativePath = file.FullName.Substring();
Console.WriteLine(".{0}.({1})", relativePath, file.LastWriteTime);
}
}

4、排序

下面代码展示了一种排序:首先按照文件名长度降序排序,然后按照文件名升序排序(不显示声明升序还是降序的,默认升序):

 IEnumerable<string> fileNames = from fileName in Directory.GetFiles(rootDirectory,searchPattern)
orderby (new FileInfo(fileName)).Length descending,fileName
select fileName;

多个排序条件用逗号隔开,重要性依次降低。但是如果我想投射一个FileInfo的集合怎么办呢?可能会有如下代码:

             IEnumerable<FileInfo> fileNames = from fileName in Directory.GetFiles(rootDirectory,searchPattern)
orderby (new FileInfo(fileName)).Length descending,fileName
select new FileInfo(fileName);

那么问题来了。看第2行与第3行,这样写会每一次访问,都会实例化两个FileInfo,十分浪费系统资源,于是C#3.0隆重推出了let字句。

5、let子句

let 子句添加的表达式可以在整个查询表达式的范围内使用,从而避免重复实例化,写法如下:

 IEnumerable<FileInfo> fileNames = from fileName in Directory.GetFiles(rootDirectory,searchPattern)
let file = new FileInfo(fileName)
orderby file.Length descending, fileName
select file;

6、编译

实际上,使用查询运算符与查询表达式对CIL CLR没有影响,编译器会将查询表达式转化成标准查询运算符。虽然属于语法糖级别的,但是平时尽可能多使用查询表达式,除非在某些特定情况下,再使用标准查询运算符。

C# 标准查询表达式的更多相关文章

  1. C#3.0新增功能09 LINQ 标准查询运算符 02 查询表达式语法

    连载目录    [已更新最新开发文章,点击查看详细] 某些使用更频繁的标准查询运算符具有专用的 C# 语言关键字语法,使用这些语法可以在查询表达式中调用这些运算符. 查询表达式是比基于方法的等效项更具 ...

  2. 《LINQ技术详解C#》-2.查询表达式翻译为标准查询操作符

    (1)透明标识符 有些翻译步骤要使用透明标识符(*)插入枚举变量. 透明标识符只在翻译过程中存在,翻译结束将不再出现. (2)翻译步骤 ①带有into连续语句的Select和Group语句 from. ...

  3. [C#] 进阶 - LINQ 标准查询操作概述

    LINQ 标准查询操作概述 序 “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法.大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了IEnumerable<T> ...

  4. .NET中那些所谓的新语法之四:标准查询运算符与LINQ

    开篇:在上一篇中,我们了解了预定义委托与Lambda表达式等所谓的新语法,这一篇我们继续征程,看看标准查询运算符和LINQ.标准查询运算符是定义在System.Linq.Enumerable类中的50 ...

  5. Linq查询表达式

    目录 1. 概述 2. from子句 3. where子句 4. select子句 5. group子句 6. into子句 7. 排序子句 8. let子句 9. join子句 10. 小结 1. ...

  6. .NET LINQ标准查询运算符

    标准查询运算符概述      “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法. 大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了 IEnumerable<T> ...

  7. LINQ 查询表达式(C# 编程指南)

    语言集成查询 (LINQ) 是一组技术的名称,这些技术建立在将查询功能直接集成到 C# 语言(以及 Visual Basic 和可能的任何其他 .NET 语言)的基础上.  借助于 LINQ,查询现在 ...

  8. 《C#本质论》读书笔记(14)支持标准查询操作符的集合接口

      14.2.集合初始化器 使用集合初始化器,程序员可以采用和数组相似的方式,在集合的实例化期间用一套初始的成员来构造这个集合. 如果没有集合初始化器,就只有在集合实例化后才能显示添加到集合中--例如 ...

  9. LinQ实战学习笔记(三) 序列,查询操作符,查询表达式,表达式树

    序列 延迟查询执行 查询操作符 查询表达式 表达式树 (一) 序列 先上一段代码, 这段代码使用扩展方法实现下面的要求: 取进程列表,进行过滤(取大于10M的进程) 列表进行排序(按内存占用) 只保留 ...

随机推荐

  1. 【原】基于64位Centos6.2的mcrouter使用简介

    此文转载必须注明原文地址,请尊重作者的劳动成果!  http://www.cnblogs.com/lyongerr/p/5040071.html 目录 文档控制... 2 1 mcrouter简介.. ...

  2. 业务中Spring使用

    不管是MVC框架还是DAO框架,在业务场景中能够通用的个人觉得AOP是一个重点,看是不是可以合理使用,其他的框架都是基础框架 ================================== 第一 ...

  3. android 自定义组合控件 顶部导航栏

    在软件开发过程中,经常见到,就是APP 的标题栏样式几乎都是一样的,只是文字不同而已,两边图标不同.为了减少重复代码,提高效率, 方便大家使用,我们把标题栏通过组合的方式定义成一个控件. 例下图: 点 ...

  4. TextView里的文 html

    一.[Android实例]实现TextView里的文字有不同颜色 转eoe:http://www.eoeandroid.com/thread-4496-1-1.html import android. ...

  5. HTTP权威指南----缓存

    缓存的处理步骤: 1.接收----缓存从网络中读取抵达的请求报文2.解析----缓存对报文进行解析,提取出URL和各种首部3.查询----缓存查看是否有本地副本可用,如果没有,就获取一份副本(并将其保 ...

  6. OSGI.NET 学习笔记--应用篇

    关于osgi.net ,想必大家也听说过,以下是自己在学习osgi.net 过程中整理出来的内容,供大家学习参与使用. 1.  OSGI.NET 与UIOSP OSGi是Open Service Ga ...

  7. LA3902 Network

    给出一棵树,对于每一个叶子节点要使得在它的k距离内至少一个节点被打了标记,(叶节点不能打标记,非叶结点也不必满足这个条件),现在已经有一个节点s被打了标记,问至少还要打几个标记(这表达能力也是捉急.. ...

  8. centos6.5没有eth0, 只有eth1, eth1无法上网

    1. cat  /etc/udev/rules.d/70-persistent-net/rules 2.将ATTR(address)=XXXXXXXX的内容 替换  文件/etc/sysconfig/ ...

  9. 二模11day2解题报告

    T1.修改文章(amend) 给出n个单词和一个长度为m的字符串,求改动多少个字符才能使字符串全由单词组成. 要说这道题还真的坑很坑超坑非常坑无敌坑--不过还是先想到了动规.毕竟要修改的前提是要组成的 ...

  10. 【Spring 2】spring的属性注入形式

    一.注入简介 spring是一个java bean的容器,它摒弃了过去通过new关键字调用类再调用类的实例的形式,通过依赖注入维护者一系列的java  bean的示例.通过spring所提供的依赖注入 ...