9、Lambda表达式

[1]Lambda表达式缩写推演,如下图:

[2]Lambda语句:=>右边有一个语句块(大括号"{}");Lambda表达式:=>右边只有一个表达式。

[3]Lambda本身无类型,不可赋值给var变量;

[4]编译时会生成一个静态方法,然后再实例化成委托传递使用;

Lambda详见:Lambda表达式

10、标准查询运算符(SQO)

"标准查询运算符"是组成语言集成查询 (LINQ) 模式的方法。大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了 "IEnumerable<T>"接口或 "IQueryable<T>" 接口。  标准查询运算符提供了包括筛选、投影、聚合、排序等功能在内的查询功能。

共有两组 LINQ 标准查询运算符,一组在类型为 "IEnumerable<T>"的对象上运行,另一组在类型为 "IQueryable<T>"的对象上运行。构成每组运算符的方法分别是 "Enumerable" 和 "Queryable" 类的静态成员。这些方法被定义为作为方法运行目标的类型的"扩展方法"。这意味着可以使用静态方法语法或实例方法语法来调用它们。

此外,许多标准查询运算符方法运行所针对的类型不是基于 IEnumerable<T>或 IQueryable<T>的类型。Enumerable类型定义两个此类方法,这些方法都在类型为 IEnumerable的对象上运行。利用这些方法(Cast<TResult>(IEnumerable)和 OfType<TResult>(IEnumerable)),您将能够在 LINQ 模式中查询非参数化或非泛型集合。 这些方法通过创建一个强类型的对象集合来实现这一点。Queryable类定义两个类似的方法(Cast<TResult>(IQueryable)和 OfType<TResult>(IQueryable)),这些方法在类型为 Queryable的对象上运行。

      各个标准查询运算符在执行时间上有所不同,具体情况取决于它们是返回单一值还是值序列。返回单一值的方法(例如 Average 和 Sum)会立即执行。  返回序列的方法会延迟查询执行,并返回一个可枚举的对象。

对于在内存中集合上运行的方法(即扩展 IEnumerable<T>的那些方法),返回的可枚举对象将捕获传递到方法的参数。在枚举该对象时,将使用查询运算符的逻辑,并返回查询结果。

与之相反,扩展 IQueryable<T>的方法不会实现任何查询行为,但会生成一个表示要执行的查询的表达式树。查询处理由源 IQueryable<T>对象处理。

标准查询语法关键字:

[1]from 子句: 查询表达式必须以 from 子句开头。

(1)指定将对其运行查询或子查询的数据源;

(2)指定一个本地范围变量,表示源序列中的每个元素。范围变量和数据源都是强类型。from子句中引用的数据源的类型必须为 IEnumerable、IEnumerable<T>或一种派生类型(如 IQueryable<T>)。

例子10-1:

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

// Create the query.
// lowNums is an IEnumerable<int>
var lowNums = from num in numbers
where num < 5
select num;

如例子10-1中,numbers为"数据源",num为"范围变量"。

[2]where 子句:

(1)where 子句用在查询表达式中,用于指定将在查询表达式中返回数据源中的"条件",并返回满足指定条件的元素。

(2)一个查询表达式可以包含多个 where 子句,一个子句可以包含多个"谓词"子表达式,在单一 where 子句内,可以使用 "&&" 和 "||" 运算符根据需要指定任意多个谓词。

在例子10-1中,where 子句筛选出除小于五的数字外的所有数字。如果移除 where 子句,则会返回数据源中的所有数字。表达式 num < 5 是应用于每个元素的谓词。

[3]select 子句:

(1)在查询表达式中,select 子句可以指定将在执行查询时产生的值的类型。

(2)该子句的结果将基于前面所有子句的计算结果以及 select 子句本身中的所有表达式。

(3)查询表达式必须以 select 子句或 group子句结束。

[4]group...by...子句:

(1)返回一个 IGrouping<TKey, TElement>对象序列,这些对象包含零个或更多个与该组的键值匹配的项 。

var stu0 =
from student in students
group student by student.Last[0];

(2)如果您想要对每个组执行附加查询操作,则可以使用 "into"上下文关键字指定一个临时标识符。使用 into 时,必须继续编写该查询,并最终用一个 select 语句或另一个 group 子句结束该查询,如下所示:

var stu1 =
from student in students
group student by student.Last[0] into g
orderby g.Key
select g;

(3)可通过orderby...thenby...指定次要排序

[5]into:可以使用 into 上下文关键字创建一个临时标识符,以便将 group、join 或 select 子句的结果存储到新的标识符中。此标识符本身可以是附加查询命令的生成器。在 group 或 select 子句中使用新标识符的用法有时称为"延续"。

string[] words = { "apples", "blueberries", "oranges", "bananas", "apricots"};
var wordGroups =
from w in words
group w by w[0] into fruitGroup
where fruitGroup.Count() >= 2
select new { FirstLetter = fruitGroup.Key, Words = fruitGroup.Count() };

[6]orderby 子句:

(1)可使返回的序列或子序列(组)按升序或降序排序。

(2)可以指定多个键,以便执行一个或多个次要排序操作。排序是由针对元素类型的默认比较器执行的。默认排序顺序为升序。还可以指定自定义比较器。  但是,只能通过基于方法的语法使用它。

string[] fruits = { "cherry", "apple", "blueberry" };
IEnumerable<string> sortAscendingQuery =
from fruit in fruits
orderby fruit //"ascending" is default
select fruit;

[7]...join...on...equals...子句:

(1)使用 join 子句可以将来自不同源序列并且在对象模型中没有直接关系的元素相关联。

(2)唯一的要求是每个源中的元素需要共享某个可以进行比较以判断是否相等的值。

(3)join句使用特殊的 "equals" 关键字比较指定的键是否相等。

(4) join子句执行的所有联接都是同等联接。

(5)join子句的输出形式取决于所执行的联接的具体类型。

(6)联接类型:内部联接; 分组联接; 左外连接;

var innerJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID
select new { ProductName = prod.Name, Category = category.Name }; //

含有 into 表达式的 join 子句称为分组联接

var innerGroupJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
select new { CategoryName = category.Name, Products = prodGroup };

在左外部联接中,将返回左侧源序列中的所有元素,即使它们在右侧序列中没有匹配的元素也是如此。若要在 LINQ 中执行左外部联接,请将 DefaultIfEmpty 方法与分组联接结合起来,以指定要在某个左侧元素不具有匹配元素时产生的默认右侧元素。可以使用 null 作为任何引用类型的默认值,也可以指定用户定义的默认类型。

var leftOuterJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
from item in prodGroup.DefaultIfEmpty(new Product { Name = String.Empty, CategoryID = 0 })
select new { CatName = category.Name, ProdName = item.Name };

[8]let 子句:

使用 "let" 关键字,可以存储子表达式的结果可以在随后的子句中使用,该关键字可以创建一个新的范围变量,并且用提供的表达式的结果初始化该变量。一旦用值初始化了该范围变量,它就不能用于存储其他值。但如果该范围变量存储的是可查询的类型,则可以对其进行查询。

string[] strings =
{
"A penny saved is a penny earned.",
"The early bird catches the worm.",
"The pen is mightier than the sword."
};
var earlyBirdQuery =
from sentence in strings
let words = sentence.Split(' ')
from word in words
let w = word.ToLower()
where w[0] == 'a' || w[0] == 'e'
|| w[0] == 'i' || w[0] == 'o'
|| w[0] == 'u'
select word;

[9]ascending 和 descending  

(1)ascending :升序是默认排序顺序,所以您无须指定它。

(2)descending :降序

IEnumerable<string> sortDescendingQuery =
from vegetable in vegetables
orderby vegetable descending
select vegetable;

[10]in:

该上下文关键字可在下面三种上下文中使用:                  

(1)foreach 语句: foreach (var v in earlyBirdQuery) {  Console.WriteLine("\"{0}\" starts with a vowel", v); }

(2)查询表达式中的 join 子句: from category in categories  join prod in products on category.ID equals prod.CategoryID

(3)泛型接口和委托中的泛型类型参数。

11、LINQ查询表达式

本质:从Reflector中可以看到Linq最后都别转换成了标准查询语句。

[1]linq类似于Sql语句,以"from"子句开始,以"select"或"group...by..."子句结束;

[2]输出是一个IEnumerable<T>或 IQueryable<T>集合;"T的类型"是由select或group子句推断出来的。

class LINQQueryExpressions
{
static void Main()
{ // Specify the data source.
int[] scores = new int[] { 97, 92, 81, 60 }; // Define the query expression.
IEnumerable<int> scoreQuery =
from score in scores
where score > 80
select score; // Execute the query.
foreach (int i in scoreQuery)
{
Console.Write(i + " ");
}
}
}

C#编程语法积累(二)的更多相关文章

  1. Java基础之编程语法(二)

    1.常量: 整型:整数,4个字节. 长整型:整数,8个字节.以L结尾. 单精度浮点数:小数,4个字节.以F结尾. 双精度浮点数:小数,8个字节. 布尔:只有两个值,真(true)或假(false),1 ...

  2. 【浅墨Unity3D Shader编程】之二 雪山飞狐篇:Unity的基本Shader框架写法&amp;颜色、光照与材质

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/40955607 作者:毛星云(浅墨)  ...

  3. C#多线程编程系列(二)- 线程基础

    目录 C#多线程编程系列(二)- 线程基础 1.1 简介 1.2 创建线程 1.3 暂停线程 1.4 线程等待 1.5 终止线程 1.6 检测线程状态 1.7 线程优先级 1.8 前台线程和后台线程 ...

  4. C#编程总结(二)多线程基础

    C#编程总结(二)多线程基础 无论您是为具有单个处理器的计算机还是为具有多个处理器的计算机进行开发,您都希望应用程序为用户提供最好的响应性能,即使应用程序当前正在完成其他工作.要使应用程序能够快速响应 ...

  5. C#编程利器之二:结构与枚举(Structure and enumeration)【转】

    C#编程利器之二:结构与枚举(Structure and enumeration) 在上一篇文章中,介绍了类如何封装程序中的对象.而实际中,出了类可以封装对象外,结构和枚举也可以封装一些对象,本文将着 ...

  6. Swift3.0基础语法学习<二>

    对象和类: // // ViewController2.swift // SwiftBasicDemo // // Created by 思 彭 on 16/11/15. // Copyright © ...

  7. VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)

    VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)-软件开发-鸡啄米 http://www.jizhuomi.com/software/141.html   上一讲中讲了VS20 ...

  8. python学习_数据处理编程实例(二)

    在上一节python学习_数据处理编程实例(二)的基础上数据发生了变化,文件中除了学生的成绩外,新增了学生姓名和出生年月的信息,因此将要成变成:分别根据姓名输出每个学生的无重复的前三个最好成绩和出生年 ...

  9. .NET 4 并行(多核)编程系列之二 从Task开始

    原文:.NET 4 并行(多核)编程系列之二 从Task开始 .NET 4 并行(多核)编程系列之二 从Task开始 前言:我们一步步的从简单的开始讲述,还是沿用我一直的方式:慢慢演化,步步为营.   ...

随机推荐

  1. LL(1)文法分析表的构造和分析过程示例

    在考完编译原理之后才弄懂,悲哀啊.不过懂了就好,知识吗,不能局限于考试. 文法: E→TE' E'→+TE'|ε T→FT ' T'→*FT'|ε F→id| (E) 一.首先判断是不是 LL(1)文 ...

  2. HTML5 元素拖拽实现 及 jquery.event.drag插件

    如上图片: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" c ...

  3. Javaweb学习笔记——(一)——————进入html

    1.html的简介 *什么是html? -HyperText Markup Language:超文本标记语言,网页语言 **超文本:超出文本的范畴,使用html可以轻松实现这些操作 **标记:html ...

  4. apache - http

    apahce 添加模块编译 httpd   # so模块用来提供DSO支持的apache核心模块 # 如果编译中包含任何DSO模块,则mod_so会被自动包含进核心. # 如果希望核心能够装载DSO, ...

  5. Python数据分析学习目录

    python数据分析学习目录 Anaconda的安装和更新 矩阵NumPy pandas数据表 matplotlib-2D绘图库学习目录                      

  6. mysql 原理 ~ binlog

    一 简介:我们会持续对binlog进行分析,但是不深入代码二 版本 5.6    格式    GTID和传统格式    传统格式     一 binlog针对具体事务注意点-1         1 u ...

  7. jquery 学习(二) - 属性操作

    html代码 <div class="n1" zdy="z1">AAA <p>1111111</p> <input t ...

  8. linux相关设置

    mysql开机自启: [root@workstudio system]# systemctl enable mysqld

  9. 【转】Python数据类型之“数字(numerics)”

    [转]Python数据类型之“数字(numerics)” 上一节内容说的是“Python基本语法”,本节主要讲下Python中的数据类型. 存储在内存中的数据通常有两个属性: 在内存中的存放位置:这个 ...

  10. UML和模式应用4:初始阶段(5)--用例编写的准则

    1.前言 本文主要介绍用例编写时所遵循的几条基本准则. 2.用例编写的准则 2.1 以本质的风格编写用例 如系统认证,而不要说 需要输入ID进行认证等 2.2 编写简洁的用例 如系统认证,不要说 这个 ...