【读书笔记】C#高级编程 第十一章 LINQ
(一)LINQ概述
语言集成查询(Language Integrated Query,LINQ)在C#编程语言中继承了查询语法,可以用相同的语法访问不同的数据源。
1、LINQ查询
var query = from r in Formula1.GetChampions()
where r.Country == "Brazil"
orderby r.Wins descending
select r;
这是一个LINQ查询,子句from、where、orderby、descending和select都是这个查询中预定义的关键字。
2、扩展方法
扩展方法在静态类中声明,定义一个静态方法,其中第一个参数定义了它扩展的类型。
例子:
public static void WriteWithTime(this string message)
{
Console.WriteLine(message + "," + DateTime.Now.ToString("yyyy-MM-dd"));
}
为了和一般的静态方法进行区分,扩展方法还需要对第一个参数使用this关键字。
现在可以使用带string类型的WriteWithTime()方法了。
例子:
string message = "test txt"; message.WriteWithTime();
定义LINQ扩展方法的一个类是System.Linq名称空间中的Enumerable。
例子:
List<int> intList = new List<int>() { 1, 2, 3, 4, 5 };
var maxIntList = intList.Where(i => i > 4);
这里使用Where扩展方法获取大于4的值。
3、推迟查询的执行
在运行期间定义查询表达式时,查询就不会运行。查询会在迭代数据项时进行。
例子:
List<int> intList = new List<int>() { 1, 2, 3, 4, 5 };
var maxIntList = intList.Where(i => i > 4);
foreach (var item in maxIntList)
{
Console.WriteLine(item);
}
intList.Add(6);
foreach (var item in maxIntList)
{
Console.WriteLine(item);
}
运行以上代码,结果如下:

需要注意的是,每次在迭代中使用查询时,都会调用扩展方法(可以检测出数据源中的变化)。但调用扩展方法ToArray()、ToList()可以改变这个操作。
例子:
List<int> intList = new List<int>() { 1, 2, 3, 4, 5 };
var maxIntList = intList.Where(i => i > 4).ToList();//调用ToList()方法
foreach (var item in maxIntList)
{
Console.WriteLine(item);
}
intList.Add(6);
foreach (var item in maxIntList)
{
Console.WriteLine(item);
}
运行以上代码,结果如下:

(二)标准的查询操作符
(三)并行LINQ
1、并行查询
例子:
var data = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8 };
var res = data.AsParallel().Where(d => d > 2);
调用AsParaller()方法进行LINQ并行查询。
2、分区器
AsParallel()方法不仅扩展了IEnumerable<T>接口,还扩展了System.Collection.Concurrent名称空间的Partitioner类。
例子
var data = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8 };
var result = Partitioner.Create(data, true).AsParallel().Where(d => d > 2);
使用Create()方法手工创建一个分区器。
3、取消
.NET提供了一种标准方式,来取消长时间运行的任务,这也适用于并行LINQ。
例子:
var data = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8 };
var cts = new CancellationTokenSource();
Task.Factory.StartNew(()=> {
try
{
var resu = data.AsParallel().WithCancellation(cts.Token).Where(d => d > 2);
Console.WriteLine("查询结束");
}
catch (OperationCanceledException ex)
{
Console.WriteLine(ex.Message);
throw;
}
});
Console.WriteLine("查询开始");
Console.WriteLine("取消?");
string input = Console.ReadLine();
if (input.ToLower().Equals("y"))
{
cts.Cancel();
}
给并行查询处添加WithCancellation()方法,参数为CancellationToken令牌为参数。当取消查询时会抛出OperationCanceledException类型的异常,捕捉异常后可以使用Cancel()方法取消查询任务。
(四)表达式树
C#编译器根据类型给lambda表达式定义不同的行为,当类型为Expression<T>,编译器就从lambda表达式中创建一个表达式树,并存储在程序集中。
例子:
1 static void Main(string[] args)
2 {
3 Expression<Func<int, bool>> expression = s => s > 1 ;
4 DisplayTree(0, "lambda", expression);
5 Console.ReadKey();
6 }
7 static void DisplayTree(int indent, string message, Expression expression)
8 {
9 string outPut = string.Format("{0} {1} ! NodeType: {2}; Expr: {3}", "".PadLeft(indent, '>'), message, expression.NodeType, expression);
10 indent++;
11 switch (expression.NodeType)
12 {
13 case ExpressionType.Constant:
14 ConstantExpression constExpr = (ConstantExpression)expression;
15 Console.WriteLine("{0} Const Value: {1}", outPut, constExpr.Value);
16 break;
17 case ExpressionType.Equal:
18 case ExpressionType.AndAlso:
19 case ExpressionType.GreaterThan:
20 BinaryExpression binExpr = (BinaryExpression)expression;
21 if (binExpr.Method != null)
22 {
23 Console.WriteLine("{0} Method: {1}", outPut, binExpr.Method.Name);
24 }
25 else
26 {
27 Console.WriteLine(outPut);
28 }
29 DisplayTree(indent, "Left", binExpr.Left);
30 DisplayTree(indent, "Right", binExpr.Right);
31 break;
32 case ExpressionType.Lambda:
33 Console.WriteLine(outPut);
34 LambdaExpression lambdaExpr = (LambdaExpression)expression;
35 foreach (var item in lambdaExpr.Parameters)
36 {
37 DisplayTree(indent, "Parameter", item);
38 }
39 DisplayTree(indent, "Body", lambdaExpr.Body);
40 break;
41 case ExpressionType.MemberAccess:
42 MemberExpression memberExpr = (MemberExpression)expression;
43 Console.WriteLine("{0} Member Name: {1}, Type: {2}", outPut, memberExpr.Member.Name, memberExpr.Type.Name);
44 DisplayTree(indent, "Member Expr", memberExpr.Expression);
45 break;
46 case ExpressionType.Parameter:
47 ParameterExpression parameExpr = (ParameterExpression)expression;
48 Console.WriteLine("{0} Param Type: {1}", outPut, parameExpr.Type.Name);
49 break;
50 default:
51 Console.WriteLine();
52 Console.WriteLine("{0} {1}", expression.NodeType, expression.Type.Name);
53 break;
54 }
55 }
【读书笔记】C#高级编程 第十一章 LINQ的更多相关文章
- 读书笔记 - js高级程序设计 - 第十一章 DOM扩展
对DOM的两个主要的扩展 Selectors API HTML5 Element Traversal 元素遍历规范 querySelector var body = document.query ...
- R in action读书笔记(15)第十一章 中级绘图 之二 折线图 相关图 马赛克图
第十一章 中级绘图 本节用到的函数有: plot legend corrgram mosaic 11.2折线图 如果将散点图上的点从左往右连接起来,那么就会得到一个折线图. 创建散点图和折线图: &g ...
- R in action读书笔记(14)第十一章 中级绘图 之一:散点图(高能预警)
第十一章中级绘图 本章内容: 二元变量和多元变量关系的可视化 绘制散点图和折线图 理解相关图 学习马赛克图和关联图 本章用到的函数有: plot hexbin ablines iplot scatte ...
- 【读书笔记】C#高级编程 第二十一章 任务、线程和同步
(一)概述 所有需要等待的操作,例如,因为文件.数据库或网络访问都需要一定的时间,此时就可以启动一个新的线程,同时完成其他任务. 线程是程序中独立的指令流. (二)Paraller类 Paraller ...
- 读书笔记 - js高级程序设计 - 第七章 函数表达式
闭包 有权访问另一个函数作用域中的变量的函数 匿名函数 函数没有名字 少用闭包 由于闭包会携带包含它的函数的作用域,因此会比其它函数占用更多的内存.过度使用闭包可能会导致内存占用过多,我们建议读者 ...
- 读书笔记 - js高级程序设计 - 第六章 面向对象的程序设计
EcmaScript有两种属性 数据属性 和 访问器属性 数据属性有4个特性 Configurable Enumerable Writable Value 前三个值的默认值都为false ...
- 读书笔记 - js高级程序设计 - 第五章 引用类型
引用类型 和 类 不是一个概念 用typeof来检测属性是否存在 typeof args.name == "string" 需要实验 访问属性的方法 .号和[] 一般情况下要 ...
- 读书笔记 - js高级程序设计 - 第四章 变量 作用域 和 内存问题
5种基本数据类型 可以直接对值操作 判断引用类型 var result = instanceof Array 执行环境 每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这 ...
- 读书笔记 - js高级程序设计 - 第三章 基本概念
启用严格模式 "use strict" 这是一个 pragma 编译指示 让编码意图更清晰 是一个重要原则 5种简单数据类型 Undefined Null Boolean Num ...
随机推荐
- RPA纳税申报机器人
1.机器人开始工作 2.机器人打开企业内部税务平台,自动下载报税底表 3.机器人自动登录地方税务局,填写报税数据 手工报税10分钟/3个表 VS 机器人报税时间2分钟/3个表 处理时间缩短80% 报税 ...
- Halcon · 曲线宽度检测算法总结
视觉检测中,直线的宽度很好检测,即两条平行线的垂直距离,而曲线的宽度检测则需要另辟蹊径. 检测图像中曲线边缘的宽度,用以判断边缘是否崩缺,总结如下五种方法: 1.图像匹配判断 概述:建立标准图像参考, ...
- 学习笔记-JDBC连接数据库操作的步骤
前言 这里我就以JDBC连接数据库操作查询的步骤作以演示,有不到之处敬请批评指正! 一.jdbc连接简要步骤 1.加载驱动器. 2.创建connection对象. 3.创建Statement对象. 4 ...
- PMP 考试常见工具与技术点总结
转载请注明出处: 网络图:项目进度活动之间的逻辑关系,用来推算关键路径,最大浮动时间等: 横道图(甘特图):以图示的方式,通过活动列表和时间刻度,来展示项目获得那个顺序和持续时间 责任分配矩阵:每件事 ...
- 爬虫(9) - Scrapy框架(1) | Scrapy 异步网络爬虫框架
什么是Scrapy 基于Twisted的异步处理框架 纯python实现的爬虫框架 基本结构:5+2框架,5个组件,2个中间件 5个组件: Scrapy Engine:引擎,负责其他部件通信 进行信号 ...
- JAVA中简单的for循环竟有这么多坑,你踩过吗
JAVA中简单的for循环竟有这么多坑,你踩过吗 实际的业务项目开发中,大家应该对从给定的list中剔除不满足条件的元素这个操作不陌生吧? 很多同学可以立刻想出很多种实现的方式,但你想到的这些实现方式 ...
- DNS 系列(一):为什么更新了 DNS 记录不生效?
我们在上网时如果想要访问到另一台机器上的内容,通常只需要直接输入一串地址,例如:www.upyun.com,就能够准确访问到自己想要访问的网站.但是实际上这只是方便我们记忆的字符形式网络标识,真正让我 ...
- DTCC 干货分享:Real Time DaaS - 面向TP+AP业务的数据平台架构
2021年10月20日,Tapdata 创始人唐建法(TJ)受邀出席 DTCC 2021(中国数据库技术大会),并在企业数据中台设计与实践专场上,发表主旨演讲"Real Time Daa ...
- LM431精密+3.3V产生电路
精密+3.3V电压通过三段可调并联稳压器LM431电路产生.LM431稳压电路如下图所示. 输出电压 UO仅与电阻 R35.R38 有关,计算公式如下: 式中常数2.5为内部基准电压,其保持恒定不变. ...
- Throwable类中3个异常处理的方法和finally代码块
/* Throwable类中定义了3个异常处理的方法 String getMessage() 返回此 throwable 的简短描述. String toString() 返回此 throwable ...