Linq系列教程二(学前基础)

来源:互联网 发布:七号零食店淘宝网址 编辑:程序博客网 时间:2024/04/27 15:41

在上一讲中,我们介绍了Linq,并且知道了Linq可以提供SQL Server数据库,XML文档、ADO.NET数据集、.NET集合、文件、字符串等查询,那么今天再来学习一个新的关键词“var”。
    首先使用“var”声明一个变量的时候不需要指定这个变量的类型,但是在声明的时候必须赋值。并且这个值不可以是null。以下是正确的示例代码:

 

// 编译后i为int类型
var i = 5;
// 编译后i为string类型
var s = "Hello";
// 编译后a 为int[]类型 
var a = new[] { 012 };
// 编译后为 expr为 IEnumerable类型
var expr =
from c 
in customers
where c.City == "London"
select c;
// 编译后anon为匿名类型
var anon = new { Name = "Terry", Age = 34 };
// 编译后list为 List类型
var list = new List();

 

 以下为错误的示例代码:
var a;
var b 
= null;

 我们从以上的代码中可以看出,可以给以“var”声明的变量赋于任何类型的值,包括内置类型,匿名类型和我们的自定义类型,但是我们必须在声明的时候赋值给变量。这是为什么呢?接下来让我们编译以下一下的代码,看看会有什么效果。

var i = 8;
= "Hello";

    好,我们开始编译。。。这时候发现编译不成功,编译器放出以下错误 
    无法将类型“string”隐式转换为“int”
    这是为什么呢?
    其实我们.NET中的“var”并非JavaScript中的万能类型,我们这里的“var”只是在声明阶段时候万能类型而已。这就解释了为什么我们在声明阶段就需要给他赋值。因为用“var”声明的变量在编译时编译器会将该类型转会有类型的变量,而该变量的类型由初始化该变量的值来定的。所以当我们用int类型的值初始化i后,那么i的类型就已经被定为int类型了,所以不可以将其他的类型赋值于它。
    从一方面来讲“var”给我们的变成带来的方便,但是在大型的程序面前会使代码变得难以理解,因为我们无法得知这个变量的集体类型,当然“var”关键字也有其特殊的运用。下面我们看下“var”在Linq中的应用。

string[] words = { "aPPLE""BlUeBeRrY""cHeRry" };
// If a query produces a sequence of anonymous types, 
// then you must also use var in the foreach statement.
var upperLowerWords =
from w 
in words
select 
new { Upper = w.ToUpper(), Lower = w.ToLower() };
// Execute the query
foreach (var ul in upperLowerWords)
{
Console.WriteLine(
"Uppercase: {0}, Lowercase: {1}", ul.Upper, ul.Lower);
}
/* Outputs:
Uppercase: APPLE, Lowercase: apple
Uppercase: BLUEBERRY, Lowercase: blueberry
Uppercase: CHERRY, Lowercase: cherry 
*/

以上的代码及输出中我们可以看到,我们可以讲查询后的结果放入匿名类型中并保存到upperLowerWords变量中,然后循环去得其中的匿名类型变量和他的值,这就是我们在Linq查询中经常用到的且非常方便的数据获取与输出方式,使用匿名类型可以拿到我们只想获取的那部分数据。
    我们在上面的代码中看到这么一句new { Upper = w.ToUpper(), Lower = w.ToLower() };其实这里声明的就是一个匿名类型的对象,因为该对象没有真实的类型,而我们在声明的同时有给该对象的成员赋了值,这又是一个新的特性叫“对象初始值设定项”,还有一个类似的“集合初始值设定项”。这些运用在日后的课程中会有很多的案例,所以在此就不多加以解释了。
    那么,关于“
var”这个关键词我们就讲到这里,有关“var”的其他特性和功能以及“匿名对象”、“对象初始值设定”和“集合初始值设定项”请朋友们参看MSDN中的相关文档。

    下面我们再来讲一个在Linq经常使用的新特性,就是“Lambda 表达式”,因为我们在Linq中只用到“Lambda表达式”的基本运用,下面我就引用一些MSDN文档上的原话进行解释并简单的介绍下这个表达式。
    “Lambda 表达式”是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托。
    所有 Lambda 表达式都使用 Lambda 运算符 =>,该运算符读为“goes to”。该 Lambda 运算符的左边是输入参数(如果有),右边包含表达式或语句块。Lambda 表达式 x => x * x 读作“x goes to x times x”,可以讲表达式分配给委托类型,如下。

delegate int del(int i);
del myDelegate 
= x => x * x;
int j = myDelegate(5); //j = 25

=> 运算符具有与赋值运算符 (=) 相同的优先级,并且是右结合运算符。
    Lambda 用在基于方法的 LINQ 查询中,作为诸如 Where 和 Where(IQueryable, String, array[]()[]) 等标准查询运算符方法的参数。
    下面为Lambda表达式的基本方式:
        (input parameters) => expression
    左边为表达式需要的参数(如果有参数的话),而且当只有一个参数时括号才是可选的,运算符的右边为我们需要对数据进行处理的一些表达式,看下面的实例:

(x, y) => x == y

上面代码为Lambda表达式,解释成我们通常使用的函数为:

bool 函数名(x,y)
{
return x == y;
}

    这样看来我们的Lambda表达式不是简单了很多。
    但这样又出现了新的问题,如果系统不清楚x,y这两个参数的类型的话在比较是很可能会出现错误显现,那么我们可以进行以下的处理

(int x, int y) => x == y

    这样就明确的要进行处理的数据类型了,那么当我们不需要使用参数时该怎么办呢?看下面代码
() => SomeMethod()

    这是在一个没有参数的表达式内执行了一个函数调用。
    以上是Lambda表达式,下面来看下Lambda语句的应用。
    Lambda 语句与 Lambda 表达式类似,只是语句括在大括号中(在此就不再用代码举例):
        (input parameters) => {statement;}
    还有一个是Lambda 表达式中的变量范围问题,下面是由MSDN给出规则:
        捕获的变量将不会被作为垃圾回收,直至引用变量的委托超出范围为止。 
        在外部方法中看不到 Lambda 表达式内引入的变量。
        Lambda 表达式无法从封闭方法中直接捕获 ref 或 out 参数。
        Lambda 表达式中的返回语句不会导致封闭方法返回。
        Lambda 表达式不能包含其目标位于所包含匿名函数主体外部或内部的 goto 语句、break 语句或 continue 语句。

    这些具体的规则我们将在日后的课堂中实践。

好了,各位亲爱的朋友们今天的基础课程就到此结束了,希望各位朋友能好好看下.NET的一些新特性,对于以后的学习之路会有更好的帮助!

文章来源:宁波.NET俱乐部
作者:小胡子&Violet

 

 

原创粉丝点击