完整word版Lambda表达式详细总结doc.docx
《完整word版Lambda表达式详细总结doc.docx》由会员分享,可在线阅读,更多相关《完整word版Lambda表达式详细总结doc.docx(62页珍藏版)》请在冰豆网上搜索。
完整word版Lambda表达式详细总结doc
Lambda表达式详细总结
(一)输入参数
在Lambda表达式中,输入参数是Lambda运算符的左边部分。
它包含参数的数量可以
为0、1或者多个。
只有当输入参数为1时,Lambda表达式左边的一对小括弧才可以省
略。
输入参数的数量大于或者等于2时,Lambda表达式左边的一对小括弧中的多个参数质检使用逗号(,)分割。
示例1
下面创建一个Lambda表达式,它的输入参数的数量为0.该表达式将显示“Thisisa
Lambdaexpression”字符串。
[csharp]viewplaincopy
1.()=>Console.WriteLine("ThisisaLambdaexpression.");
分析2
由于上述Lambda表达式的输入参数的数量为0,因此,该Lambda表达式的左边部分的
一对小括弧不能被省略。
示例2
下面创建一个Lambda表达式,它的输入参数包含一个参数:
m。
该表达式将计算m参
数与2的乘积。
[csharp]viewplaincopy
1.m=>m*2;
分析2
上述Lambda表达式的输入参数省略了一对小括弧,它与“(m)=>m*2”Lambda表达式
是等效的。
示例3
下面创建一个Lambda表达式,它的输入参数包含两个参数:
m和n。
该表达式将计算
m和n参数的乘积。
[csharp]viewplaincopy
1.(m,n)=>m*n;
(二)表达式或语句块
多个Lambda表达式可以构成Lambda语句块。
语句块可以放到运算符的右边,作为
Lambda的主体。
根据主题不同,Lambda表达式可以分为表达式Lambda和语句
Lambda。
语句块中可以包含多条语句,并且可以包含循环、方法调用和if语句等。
示例1
下面创建一个Lambda表达式,它的右边部分是一个表达式。
该表达式计算m参数的平
方值。
[csharp]viewplaincopy
1.m=>m*n;
分析1
如果Lambda表达式的右边部分是一个语句块,那么该语句块必须被"{"和"}"包围。
示例2
下面创建一个Lambda表达式,它的输入参数包括两个参数:
m和n。
该表达式的右边包
含2个表达式;第一个表达式计算m和n参数的乘积,结果保存为result变量;第二个
表达式显示result变量的值。
[csharp]viewplaincopy
1.(m,n)=>{intresult=m*n;Console.WriteLine(result);}
分析2
上述Lambda表达式的右边部分包含2个表达式,因此,该表达式的右边部分必须被"{"
和"}"包围。
(三)查询表达式
查询表达式是一种使用查询语法表示的表达式,它用于查询和转换来自任意支持LINQ的
数据源中的数据。
查询表达式使用许多常见的C#语言构造,易读简洁,容易掌握。
它由
一组类似于SQL或XQuery的声明性语法编写的子句组成。
每一个子句可以包含一个或多
个C#表达式。
这些C#表达式本身也可能是查询表达式或包含查询表达式。
●查询表达式必须以from子句开头,以select或group子句结束。
第一个from子句和
最后一个select子句或group子句之间,可以包含一个活多个where子句、let子句、
join子句、orderby子句和group子句,甚至还可以是from子句。
它包括8个基本
子句,具体说明如下所示。
●from子句:
指定查询操作的数据源和范围变量。
●select子句:
指定查询结果的类型和表现形式。
●where子句:
指定筛选元素的逻辑条件。
●let子句:
引入用来临时保存查询表达式中的字表达式结果的范围变量。
●orderby子句:
对查询结果进行排序操作,包括升序和降序。
●group子句:
对查询结果进行分组。
●into子句:
提供一个临时标识符。
join子句、group子句或select子句可以通过该标识
符引用查询操作中的中坚结果。
●join子句:
连接多个用于查询操作的数据源。
示例1
下面创建一个查询表达式query,该查询表达式查询arr数组中的每一个元素。
int[]arr=newint[]{0,1,2,3,4,5,6,7,8,9};
分析1
[csharp]viewplaincopy
1.
varquery1=fromn
inarr
2.
selectn;
示例2
下面创建一个查询表达式query2.该查询表达式查询arr数组中大于6的元素。
[csharp]viewplaincopy
1.int[]arr=newint[]{0,1,2,3,4,5,6,7,8,9};
2.
varquery2=fromn
inarr
3.
wheren>6
4.
selectn;
分析2
变量只是保存查询操作,而不是查询的结果。
当查询表达式执行查询操作时,才会计算该查询表达式的结果。
以上两个变量的类型都属于集合类型。
(四)from子句
from子句用来指定查询表达式的数据源和范围变量。
它是查询表达式的必有部分,并且它
出现在最开始。
数据源不但可以包括查询本身的数据源,而且还可以包括子查询的数据源。
范围变量用来表示数据源序列中的每一个元素。
注意:
from子句指定的数据源的类型必须为IEnumerable,IEnumerable或一种派生类型。
示例1
下面创建一个查询表达式query。
该查询表达式查询arr数组中的每一个元素。
在query查
询表达式中,arr数组为数据源,n为范围变量。
n范围变量的类型arr数据源的元素类型。
分析1
[csharp]viewplaincopy
1.int[]arr=newint[]{0,1,2,3,4,5,67,8,9};
2.varquery=fromninarr
3.selectn;
下面我们来学习数据源和包含不同的from子句查询表达式。
数据源:
指定数据的来源,它的形式可以为静态数组、动态数组(Arraylist)、集合、数
据集(DataSet)、数据表、MML片段、MML文件等。
如果数据源实现了IEnumerable接口,那么编译器可以推断范围变量的类型为其元素
类型。
例如:
数据源的类型为IEnumerable,那么可以推断出范围变量的类型
为UseInfo。
示例2
下面创建一个查询表达式query。
该查询表达式查询list反省数组中的每一个元素。
在
query查询表达式中,list反省数组为数据源。
u为范围变量。
u范围变量的类型为list数
据源的元素类型(UserInfo)。
分析2
[csharp]viewplaincopy
1.Listlist=...
2.varquery=fromuinlist
3.selectu;
如果当数据源是非泛型
IEnumerable
类型(如
ArrayList
等)时,需要显示指定范围变量
的类型。
示例
3
下面创建一个查询表达式
query
。
该查询表达式查询
list
数组中的每一个元素。
在
query
查询表达式中,
list
数组为数据源,
u为范围变量。
u范围变量的类型被指定为
list
数据源
的元素类型(
UserInfo
)。
分析
3
[csharp]
viewplain
copy
1.ArrayListlist=newArrayList();
2.list.Add(...);
3....
4.varquery=fromUserInfouinlist
5.selectu;
包含单个from子句的查询表达式
在查询表达式中,from子句至少有一个。
当from子句只有一个时,构成的查询表达式被
称为包含单个from子句的查询表达式。
一般的,包含单个from子句的查询表达式只包
含一个数据源。
示例4
下面创建一个查询表达式query。
该查询表达式查询arr数组中的每一个元素,它就是一
个包含单个from子句的查询表达式。
分析4
[csharp]viewplaincopy
1.int[]arr=newint[]{0,1,12,3,4,5,6,7,8,9};
2.varquery=fromninarr
3.selectn;
包含多个from子句的查询表达式
在查询表达式中,当from子句有两个或两个以上时,构成的查询表达式被称为包含多个
from子句的查询表达式。
示例5
下面创建一个查询表达式query。
该查询表达式包含两个from子句,他们分别查询两个
独立的数据源;arr1数组和arr2数组。
最后,使用select子句计算当前元素的和。
分析5
[csharp]viewplaincopy
1.
int
[]arr1=
new
int
[]{0,1,2,3,4,5,6,7,8,9};
2.
int
[]arr2=
new
int
[]{0,1,2,3,4,5,6,7,8,9};
3.
varquery=froma
inarr1
4.
fromb
in
arr2
5.selecta+b;
包含符合from子句的查询表达式
在查询表达式中,有可能查询表达式的数据源中的每一个元素本身也作为该查询表达式的
数据源。
那么要查询数据源中的每一个元素中的元素,则需要使用符合from子句。
符合
from子句类似于嵌套的foreach语句。
示例6
下面创建一个名称为Test的类,该类包含两个字段:
Name和AliasName。
其中,
Name字段的类型为string,AliasName字段的类型为string类型列表。
因此,它也可
以作为子查询表达式的数据源。
分析6
[csharp]viewplaincopy
1.publicclassTest
2.{
3.
Public
stringName;
4.
PublicList<
string>AliasName;
5.}
示例7
下面创建一个查询表达式query。
该查询表达式包含了一个符合from子句:
第一个from
子句查询list泛型集合;第二个from子句查询list集合中元素的AliasName字段,为第
一个from子句的子查询。
最后,使用select子句将u变量的Name属性的值和name
变量的值拼接为一个字符串。
分析7
[csharp]viewplaincopy
1.Listlist=...
2.
varquery=fromu
inlist
3.
fromname
inu.AliasName
4.selectu.Name+name;
(五)select子句
select子句用来指定将在执行查询时产生的值的类型。
查询表达式必须以select子句或
group子句结束。
示例1
下面创建一个查询表达式query。
该查询表达式查询arr数组中的每一个元素。
分析1
[csharp]viewplaincopy
1.int[]arr=newint[]{0,1,2,3,4,5,6,7,8,9};
2.varquery=fromninarr
3.selectn;
示例2
下面创建一个查询表达式
query。
该查询表达式查询arr数组中的每一个元素和
10的乘
积。
[csharp]viewplaincopy
1.int[]arr=newint[]{0,1,2,3,4,5,6,7,8,9};
2.varquery=fromninarr
3.selectn*10;
分析2
select子句中的“n*10表”达式决定了查询结果的表现形式,即计算每一个元素和
10的乘
积。
示例3
下面创建一个查询表达式query。
该查询表达式查询arr数组中的每一个元素,查询结果是
一个对象的集合对象包含两个属性:
ID和Name,它在select子句中由匿名对象初始化器
创建。
每一个对象的ID属性的值是当前元素的值、Name属性的值为元素的值的字符串的表现形式。
分析3
[csharp]viewplaincopy
1.int[]arr=newint[]{0,1,2,3,4,5,6,7,8,9};
2.
varquery=fromn
inarr
3.
select
new
4.{
5.ID=n,
6.Name=n.ToString()
7.};
(六)where子句
where子句用来指导将在查询表达式中返回数据源中的哪些元素。
它将一个布尔条件应用
于数据源中的每个元素,并返回指定条件的元素。
查询表达式可以包含一个或多个where
子句。
示例1
下面创建一个查询表达式query。
该查询表达式从arr数组中查询小于3的元素
[csharp]viewplaincopy
1.int[]arr=newint[]{0,1,2,3,4,5,6,7,8,9};
2.varquery=fromninarr
3.wheren<3
4.selectn;
分析1
上述where子句只包含一个布尔表达式“n<3”,该表达式将筛选小于3的元素。
在一个where子句中,也可以包含多个布尔表达式,各个表达式直接使用逻辑运算符(如
&&和||)分隔。
示例2
下面创建一个查询表达式query。
该查询表达式从arr数组中查询大于3且小于6的元
素。
[csharp]viewplaincopy
1.int[]arr=newint[]{0,1,2,3,4,5,6,7,8,9};
2.
varquery=fromn
inarr
3.
wheren>3&&n<6
4.
selectn;
分析2
上述where子句包含两个布尔表达式"n>3"和"n<6",它们共同指定将筛选大于3且小于6
的元素。
这两个布尔表达式使用&&运算符链接,即计算这两个布尔表达式的逻辑与。
where子句不但可以包含布尔表达式,而且还可以包含返回布尔值的方法。
示例3
下面创建一个查询表达式query.该查询表达式从arr数组中查询为偶数的元素。
[csharp]viewplaincopy
1.int[]arr=newint[]{0,1,2,3,4,5,6,7,8,9};
2.privateboolIsEven(inti)
3.{
4.returni%2==0?
true:
false;
5.}
6.
varquery=fromn
inarr
7.
wehreIsEven(n)
8.
selectn;
分析3
上述where子句包含一个返回布尔值的方法"IsEven(inti)"。
该方法判定元素是否为偶
数。
如果是,则返回true,否则返回false。
(七)let子句
let子句用来创建一个新的范围变量,它用于存储子表达式的结果。
let子句使用编程者提
供的表达式的结果初始化该变量。
一旦初始化了该范围变量的值,它就不能用于存储其他
的值。
示例1
下面创建一个查询表达式query。
该查询表达式从arr数组中查询为偶数的元素。
[csharp]viewplaincopy
1.int[]arr=newint[]{0,1,2,3,4,5,6,7,8,9};
2.
varquery=fromn
inarr
3.
letisEven=
returnn%2==0?
true:
false;
4.whereisEven
5.selectn;
分析1
"returnn%2==0?
true:
false"表达式判断n元素是否为偶数。
如果是,则返回true,否则
返回false。
“letisEven=returnn%2==0?
true:
false”表达式使用let子句创建新的范
围变量isEven,用来保存"returnn%2==0?
true:
false"表达式的结果。
"whereisEven"表
达式使用where子句筛选isEven的值为true的元素。
(八)orderby子句
orderby子句可使返回的查询结果按升序或者降序排序。
升序由关键字ascending指定,
而降序由关键字descending指定。
注意:
orderby子句默认排序方式为升序。
示例1
下面创建一个查询表达式query。
该查询表达式从arr数组中查询大于1且小于6的元
素,并且按照n元素对查询结果进行降序排序。
[csharp]viewplaincopy
1.int[]arr=newint[]{0,1,2,3,4,5,6,7,8,9};
2.varquery=fromninarr
3.wheren>1&&n<6
4.orderbyndescending
5.selectn;
分析1
orderby子句可以包含一个或多个排序表达式,各个排序表达式使用逗号(,)分隔。
示例2
下面创建一个查询表达式query。
该查询表达式从arr数组中查询大于1且小于6的元
素。
它使用orderby子句对查询结果进行排序,且包含两个排序关键字,具体说明如下所
示:
n%2:
按照升序排序;n:
按照降序排序。
注意:
n%2排序关键字优先级大于n排序关键字。
因此,该查询表达式的结果首先按照
n%2排序关键字升序排序,然后在按照n排序关键字降序排序。
分析2
在"orderbyn%2ascending,ndescending"表达式中,第一个排序关键字后的
"ascending"可以省略。
因为默认排序方式为升序。
(九)group子句
group子句用来将查询结果分组,并返回一对象序列。
这些对象包含零个或更多个与改组
的key值匹配的项,还可以使用group子句结束查询表达式。
注意:
每一个分组都不是单个元素,而是一个序列(也属于集合)。
示例1
下面创建一个查询表达式query。
该查询表达式从arr数组中查询大于1且小于6的元
素,并且按照n%2表达式的值对查询结果进行分组。
[csharp]viewplaincopy
1.int[]arr=newint[]{0,1,2,3,4,5,6,7,8,9};
2.varquery=fromninarr
3.wheren>1&&n<6
4.groupnbyn%2;
分析1
query查询表达式的结果是一个序列(类型为IEnumerable>),
该序列的元素类型为IGrouping.其实,该查询结果中的元素也是一个序列。
示例2
下面使用两个foreach语句显示query查询表达式结果中每一个元素的值。
[csharp]viewplaincopy
1.foreach(varginquery)
2.{
3.foreach(varoing)
4.{
5.Console.WriteLine(0);
6.}
7.}
分析2
使用group子句对查询结果分组后,每一个分组都存在一个键(由key属性表示)。
通
过key属性可以获取每一个分组的键的值。
(十)into子句
into子句可以用来创建一个临时标识符,将group、join或sel