(一)LINQ概述

语言集成查询(Language Integrated Query,LINQ)在C#编程语言中继承了查询语法,可以用相同的语法访问不同的数据源。

1、LINQ查询

  1. var query = from r in Formula1.GetChampions()
  2.  
  3. where r.Country == "Brazil"
  4.  
  5. orderby r.Wins descending
  6.  
  7. select r;

这是一个LINQ查询,子句from、where、orderby、descending和select都是这个查询中预定义的关键字。

2、扩展方法

扩展方法在静态类中声明,定义一个静态方法,其中第一个参数定义了它扩展的类型。

例子:

  1. public static void WriteWithTime(this string message)
  2. {
  3. Console.WriteLine(message + "," + DateTime.Now.ToString("yyyy-MM-dd"));
  4. }

为了和一般的静态方法进行区分,扩展方法还需要对第一个参数使用this关键字。

现在可以使用带string类型的WriteWithTime()方法了。

例子:

  1. string message = "test txt";
  2.  
  3. message.WriteWithTime();

定义LINQ扩展方法的一个类是System.Linq名称空间中的Enumerable。

例子:

  1. List<int> intList = new List<int>() { 1, 2, 3, 4, 5 };
  2.  
  3. var maxIntList = intList.Where(i => i > 4);

这里使用Where扩展方法获取大于4的值。

3、推迟查询的执行

在运行期间定义查询表达式时,查询就不会运行。查询会在迭代数据项时进行。

例子:

  1. List<int> intList = new List<int>() { 1, 2, 3, 4, 5 };
  2.  
  3. var maxIntList = intList.Where(i => i > 4);
  4.  
  5. foreach (var item in maxIntList)
  6.  
  7. {
  8.  
  9. Console.WriteLine(item);
  10.  
  11. }
  12.  
  13. intList.Add(6);
  14.  
  15. foreach (var item in maxIntList)
  16.  
  17. {
  18.  
  19. Console.WriteLine(item);
  20.  
  21. }

运行以上代码,结果如下:

需要注意的是,每次在迭代中使用查询时,都会调用扩展方法(可以检测出数据源中的变化)。但调用扩展方法ToArray()、ToList()可以改变这个操作。

例子:

  1. List<int> intList = new List<int>() { 1, 2, 3, 4, 5 };
  2.  
  3. var maxIntList = intList.Where(i => i > 4).ToList();//调用ToList()方法
  4.  
  5. foreach (var item in maxIntList)
  6.  
  7. {
  8.  
  9. Console.WriteLine(item);
  10.  
  11. }
  12.  
  13. intList.Add(6);
  14.  
  15. foreach (var item in maxIntList)
  16.  
  17. {
  18.  
  19. Console.WriteLine(item);
  20.  
  21. }

运行以上代码,结果如下:

(二)标准的查询操作符

参考:http://www.cnblogs.com/heyuquan/p/Linq-to-Objects.html

(三)并行LINQ

1、并行查询

例子:

  1. var data = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8 };
  2.  
  3. var res = data.AsParallel().Where(d => d > 2);

调用AsParaller()方法进行LINQ并行查询。

2、分区器

AsParallel()方法不仅扩展了IEnumerable<T>接口,还扩展了System.Collection.Concurrent名称空间的Partitioner类。

例子

  1. var data = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8 };
  2.  
  3. var result = Partitioner.Create(data, true).AsParallel().Where(d => d > 2);

使用Create()方法手工创建一个分区器。

3、取消

.NET提供了一种标准方式,来取消长时间运行的任务,这也适用于并行LINQ。

例子:

  1. var data = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8 };
  2. var cts = new CancellationTokenSource();
  3. Task.Factory.StartNew(()=> {
  4. try
  5. {
  6. var resu = data.AsParallel().WithCancellation(cts.Token).Where(d => d > 2);
  7. Console.WriteLine("查询结束");
  8. }
  9. catch (OperationCanceledException ex)
  10. {
  11. Console.WriteLine(ex.Message);
  12. throw;
  13. }
  14. });
  15. Console.WriteLine("查询开始");
  16. Console.WriteLine("取消?");
  17. string input = Console.ReadLine();
  18. if (input.ToLower().Equals("y"))
  19. {
  20. cts.Cancel();
  21. }

给并行查询处添加WithCancellation()方法,参数为CancellationToken令牌为参数。当取消查询时会抛出OperationCanceledException类型的异常,捕捉异常后可以使用Cancel()方法取消查询任务。

(四)表达式树

C#编译器根据类型给lambda表达式定义不同的行为,当类型为Expression<T>,编译器就从lambda表达式中创建一个表达式树,并存储在程序集中。

例子:

  1. 1 static void Main(string[] args)
  2. 2 {
  3. 3 Expression<Func<int, bool>> expression = s => s > 1 ;
  4. 4 DisplayTree(0, "lambda", expression);
  5. 5 Console.ReadKey();
  6. 6 }
  7. 7 static void DisplayTree(int indent, string message, Expression expression)
  8. 8 {
  9. 9 string outPut = string.Format("{0} {1} ! NodeType: {2}; Expr: {3}", "".PadLeft(indent, '>'), message, expression.NodeType, expression);
  10. 10 indent++;
  11. 11 switch (expression.NodeType)
  12. 12 {
  13. 13 case ExpressionType.Constant:
  14. 14 ConstantExpression constExpr = (ConstantExpression)expression;
  15. 15 Console.WriteLine("{0} Const Value: {1}", outPut, constExpr.Value);
  16. 16 break;
  17. 17 case ExpressionType.Equal:
  18. 18 case ExpressionType.AndAlso:
  19. 19 case ExpressionType.GreaterThan:
  20. 20 BinaryExpression binExpr = (BinaryExpression)expression;
  21. 21 if (binExpr.Method != null)
  22. 22 {
  23. 23 Console.WriteLine("{0} Method: {1}", outPut, binExpr.Method.Name);
  24. 24 }
  25. 25 else
  26. 26 {
  27. 27 Console.WriteLine(outPut);
  28. 28 }
  29. 29 DisplayTree(indent, "Left", binExpr.Left);
  30. 30 DisplayTree(indent, "Right", binExpr.Right);
  31. 31 break;
  32. 32 case ExpressionType.Lambda:
  33. 33 Console.WriteLine(outPut);
  34. 34 LambdaExpression lambdaExpr = (LambdaExpression)expression;
  35. 35 foreach (var item in lambdaExpr.Parameters)
  36. 36 {
  37. 37 DisplayTree(indent, "Parameter", item);
  38. 38 }
  39. 39 DisplayTree(indent, "Body", lambdaExpr.Body);
  40. 40 break;
  41. 41 case ExpressionType.MemberAccess:
  42. 42 MemberExpression memberExpr = (MemberExpression)expression;
  43. 43 Console.WriteLine("{0} Member Name: {1}, Type: {2}", outPut, memberExpr.Member.Name, memberExpr.Type.Name);
  44. 44 DisplayTree(indent, "Member Expr", memberExpr.Expression);
  45. 45 break;
  46. 46 case ExpressionType.Parameter:
  47. 47 ParameterExpression parameExpr = (ParameterExpression)expression;
  48. 48 Console.WriteLine("{0} Param Type: {1}", outPut, parameExpr.Type.Name);
  49. 49 break;
  50. 50 default:
  51. 51 Console.WriteLine();
  52. 52 Console.WriteLine("{0} {1}", expression.NodeType, expression.Type.Name);
  53. 53 break;
  54. 54 }
  55. 55 }

【读书笔记】C#高级编程 第十一章 LINQ的更多相关文章

  1. 读书笔记 - js高级程序设计 - 第十一章 DOM扩展

      对DOM的两个主要的扩展 Selectors API HTML5  Element Traversal 元素遍历规范 querySelector var body = document.query ...

  2. R in action读书笔记(15)第十一章 中级绘图 之二 折线图 相关图 马赛克图

    第十一章 中级绘图 本节用到的函数有: plot legend corrgram mosaic 11.2折线图 如果将散点图上的点从左往右连接起来,那么就会得到一个折线图. 创建散点图和折线图: &g ...

  3. R in action读书笔记(14)第十一章 中级绘图 之一:散点图(高能预警)

    第十一章中级绘图 本章内容: 二元变量和多元变量关系的可视化 绘制散点图和折线图 理解相关图 学习马赛克图和关联图 本章用到的函数有: plot hexbin ablines iplot scatte ...

  4. 【读书笔记】C#高级编程 第二十一章 任务、线程和同步

    (一)概述 所有需要等待的操作,例如,因为文件.数据库或网络访问都需要一定的时间,此时就可以启动一个新的线程,同时完成其他任务. 线程是程序中独立的指令流. (二)Paraller类 Paraller ...

  5. 读书笔记 - js高级程序设计 - 第七章 函数表达式

      闭包 有权访问另一个函数作用域中的变量的函数 匿名函数 函数没有名字 少用闭包 由于闭包会携带包含它的函数的作用域,因此会比其它函数占用更多的内存.过度使用闭包可能会导致内存占用过多,我们建议读者 ...

  6. 读书笔记 - js高级程序设计 - 第六章 面向对象的程序设计

      EcmaScript有两种属性 数据属性 和 访问器属性 数据属性有4个特性 Configurable Enumerable Writable Value   前三个值的默认值都为false   ...

  7. 读书笔记 - js高级程序设计 - 第五章 引用类型

      引用类型 和 类 不是一个概念 用typeof来检测属性是否存在 typeof args.name == "string"  需要实验 访问属性的方法 .号和[] 一般情况下要 ...

  8. 读书笔记 - js高级程序设计 - 第四章 变量 作用域 和 内存问题

      5种基本数据类型 可以直接对值操作 判断引用类型 var result = instanceof Array 执行环境 每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这 ...

  9. 读书笔记 - js高级程序设计 - 第三章 基本概念

    启用严格模式 "use strict" 这是一个 pragma 编译指示 让编码意图更清晰  是一个重要原则 5种简单数据类型 Undefined Null Boolean Num ...

随机推荐

  1. OpenLayers入门(一)

    OpenLayers简介 OpenLayers(https://openlayers.org/)是一个用来帮助开发Web地图应用的高性能的.功能丰富的JavaScript类库,可以满足几乎所有的地图开 ...

  2. 从20s优化到500ms,我用了这三招

    前言 接口性能问题,对于从事后端开发的同学来说,是一个绕不开的话题.想要优化一个接口的性能,需要从多个方面着手. 其实,我之前也写过一篇接口性能优化相关的文章<聊聊接口性能优化的11个小技巧&g ...

  3. Netty 如何高效接收网络数据?一文聊透 ByteBuffer 动态自适应扩缩容机制

    本系列Netty源码解析文章基于 4.1.56.Final版本,公众号:bin的技术小屋 前文回顾 在前边的系列文章中,我们从内核如何收发网络数据开始以一个C10K的问题作为主线详细从内核角度阐述了网 ...

  4. P2575 高手过招 题解

    题目描述 我们考虑如何把问题转换成博弈论来求解. 我们对于每一行之前都加上一个空格. 设原来这一行的空格个数是 \(C\) ,那么此时空格个数变成 \(C + 1\) . 然后按照从左到右的顺序给每一 ...

  5. pytorch 基础内容

    一些基础的操作: import torch as th a=th.rand(3,4) #随机数,维度为3,4的tensor b=th.rand(4)print(a)print(b) a+b tenso ...

  6. SpringBoot事件监听器源码分析

    本文涉及到Spring的监听器,如果不太了解请先阅读之前的Spring监听器的文章. SpringBoot事件监听器初始化 SpringBoot中默认定义了11个事件监听器对象,全部定义在META-I ...

  7. Redis系列3:高可用之主从架构

    Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 1 主从复制介绍 上一篇<Redis系列2:数据持久化提高可用性>中,我们介绍了Redis中的数据 ...

  8. 项目配置yaml

    springboot的一些配置 #当循环调用时,就会报错 spring.main.allow-circular-references=true #配置mvc是需要使用一个@EnableWebMvc,不 ...

  9. 计算机二级Python(第一阶段)

    介绍   本篇文章主要针对于计算机二级考试的崽崽,当然想了解Python和学习Python的崽崽也是可以看本篇文章的:毕竟,手机和电脑都可以运行Python:本篇我文章虽然是笔记,但是也纯靠手打,希望 ...

  10. OpenWrt之feeds.conf.default详解

    目录 OpenWrt之feeds.conf.default详解 文件内容 命令解释 src-svn与src-gitsvn src-git与src-git-full src-cpy与src-link 其 ...