Linq 学习(一)

LINQ 使查询成为了 .NET 中头等的编程概念,被查询的数据可以是 XML LINQ to XML )、 Databases LINQ to SQL LINQ to Dataset LINQ to Entities )和对象( LINQ to Objects )。 LINQ 也是可扩展的,允许你建立自定义的 LINQ 数据提供者(比如: LINQ to Amazon LINQ to NHibernate LINQ to LDAP

 

 

新的语言特性

I/ 自动属性

public
 class
 Point {
private int _x, _y;
public int X {
get { return _x; }
set { _x = value; }
}
public int Y {
get { return _y; }
set { _y = value; }
}
}

上面的代码简单的定义了一个拥有两个属性的类。现在,使用VS2008中的C#编译器,我们就可以用自动属性写的更简单, 它能自动的生成带有get /set 操 作的私有域。

public
 class
 Point {
public int X { get; set; }
public int Y { get; set; }
}

(这个特性和LINQ还没有关系)

II/ 局部变量类型

使用这个特性,声明一个局部变量,它的具体类型是通过初始化表达式来推断。这点是通过var 关键词完成的。我们可以写出如下 的代码:

var num = 50;
var str = "simple string" ;
var obj = new myType();

var numbers = new int [] {1,2,3};
var dic = new Dictionary<int ,myType>();

编译器会生成IL中间代码,就如同我们编译了下面的代码:

int
 num = 50;
string str = "simple string" ;
myType obj = new myType();
int [] numbers = new int [] {1,2,3};



Dictionary<int ,myType> dic = new Dictionary<int ,myType>();

注意,这里并不存在无类型的变量,也没有推迟类型的绑定。编译器是从右边的赋值语句来自动推断和声明变量的类型的,var 关键词是一个强类型的变量引用。

III/ 对象初始化和集合初始化

 

Point p = new
 Point();
p.X = 0;
p.Y = 0;

现在,使用对象初始化,就可以像这样子来重写:

Point p = new
 Point() { X = 0, Y = 0 };

这个特性也可以使用在集合上,看看下面这段示例:

List points = new
 List {   new
 Point { X = 2,  Y = 5 },    new
 Point { X = 1, Y = -10 },    new
 Point { X = 3, Y = 0 }};

注意,编译器会产生和上面相等价的长一些的代码,它依次调用Add() 方 法来在集合里添加元素。

 

IV/ 匿名类型

这个语言特性让我们可以定义内嵌的类型,而不需要显式地定义一个类型。换句话说,假设我们没有定义Point 类,却要使用一个Point 对象 (即类型是匿名的)。我们可以使用上面提到的对象初始化语法,但不用指定类型名:

var p = new

{X = 0, Y = 2};

在VS2008中,你仍然可以使用智能感应。所以如果你继续使用变量p,就会得到这个匿名类型的属性列表。

 

V/ Lambda表达式

在C#2.0中引入了匿名方法,允许在需要委托的地方写一个代码块。匿名方法提供了函数式程序语言的能力,语法显得很简 洁。Lambda表达式提供了一个更简洁的语法来写匿名方法。一个Lambda表达式就是一个参数列表(可以隐式类型),然后是一个=>符号,然后 是一个表达式或者一个语句块。

作为一个示例,我们定义一个委托类型MyDeleg

delegate
 R MyDeleg(A arg);

然后我们就可以使用匿名方法:

MyDeleg IsPositive = delegate
(int
  num) {
return num > 0;
 };

我们也可以使用新的Lambda表达式来写:

MyDeleg IsPositive = num => num > 0;

VI/ 扩展方法

扩展方法可以使你来扩展一个已存在的类型,增加它的方法,而无需继承它或者重新编译。所以不像为对象写助手方法,扩展方法 可以直接是对象自己的一部分。

一个示例,假设我们想要验证一个string 是不是合法的 Email地址,我们可以编写一个方法,输入为一个string 并且返回true 或者false 。现在,使用扩展方 法,我们可以如下这样做:

public
 static class
 MyExtensions {
public static bool IsValidEmailAddress(this string s) {
Regex regex = new Regex( @"^[w-.]+@([w-]+.)+[w-]{2,4}$" );
return regex.IsMatch(s);
}
}

我们定义了一个带有静态方法的静态类。注意,那个静态方法在参数类型string 前 面有一个this 关键词,这会告诉编译器这个特殊的扩展方法会增加给string 类型的对象。于是我们就可以在string 中 调用这个成员方法:

using
 MyExtensions;

string email = Request.QueryString["email" ];

if ( email.IsValidEmailAddress() ) {
// ...
}

值得提出的是,LINQ就是使用了System.Linq 命 名空间中的扩展方法(比如where()、orderby()、select()、sum()、average()等等),而且它定义了标准查询操作符, 可以用来查询关系数据库、XML和任何实现了IEnumerable<T> 接口 的.NET对象。

VII/ 查询语法

查询表达式提供了一个语言集成的语法来查询,它特别像关系和层次查询语言比如SQL和XQuery。使用LINQ操作符 (也就是from...where...select)写查询很方便,Visual Studio为它提供了很好的智能感知和编译时的检查支持。
当C#编译器遇到了一个查询语法表达式时,实际上它会被转化为使用扩展方法和Lambda表达式的方法调用。

我们举一个例子来解释这个:

var result = from c in
 Customers
  where c.City.StartsWith("B" )
orderby c.LastName
select new { c.FirstName, c.LastName, c.Address };

上面的代码等价于:

var result = Customers.Where( c => c.City.StartsWith("B"
) )
.OrderBy( c => c.LastName )
.Select( c => new { c.FirstName, c.LastName, c.Address } );

使用查询语法的好处还有它会使代码更简单更易读。
同时注意,查询表达式以from 开头,以select 或者group 结尾。

最后注意

C#3.0中新引入的几个特性大多数都仅仅是“编译器技巧”或者“语法糖”,其实编译器生成的IL中间代码和原来的是一样 的,这样他们就独立于framework和CLR运行时。但是,他们确实需要某些framework的支持,比如System.Core.dll 程序集。这就是为什么扩展方法仍然需要依靠于System.Core.dll 里包含的System.Runtime.CompilerServices.ExtensionAttribute
另一方面,查询表达式只是实现了到扩展方法的映射,它包含在System.Linq, System.Data.LinqSystem.Xml.Linq 命名空 间中。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值