惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
Stack Overflow Blog
Stack Overflow Blog
人人都是产品经理
人人都是产品经理
The GitHub Blog
The GitHub Blog
Engineering at Meta
Engineering at Meta
Vercel News
Vercel News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Y
Y Combinator Blog
The Cloudflare Blog
Last Week in AI
Last Week in AI
B
Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
V
Visual Studio Blog
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
Google DeepMind News
Google DeepMind News
D
DataBreaches.Net
博客园 - 司徒正美
B
Blog RSS Feed
Microsoft Azure Blog
Microsoft Azure Blog
罗磊的独立博客
Hugging Face - Blog
Hugging Face - Blog
L
LangChain Blog

博客园 - 一麦

GridView的增删改查和分页 - 一麦 - 博客园 团队开发之环境搭建 .Net下SqlServer命名规范 XXX公司CRM项目开发日志 Coolite Toolkit学习笔记 反射学习 常用正则表达式 正则表达式基本用法 正则表达式基础 页面生命周期小结 设计模式小结 Asp.net 中HttpHandler,HttpModule,IHttpHandlerFactory的原理与应用(一) 3.x新特性 FileStream读写文件【StreamWriter 和 StreamReader】 .NET常用集合类 面向对象点滴 C#基础点滴 全新对待.net---一次全面的旅程 委托和事件--一直以来的痛
LINQ新特性简介及入门教程
一麦 · 2009-05-06 · via 博客园 - 一麦

出处:http://www.msproject.cn/article/Cs3LinqFeatures.aspx

翻译
Amro Khasawneh 著 Understanding LINQ (C#)
flanker译(还请指教啊)

简介

本文主要是关注于LINQ——我认为是VS2008(.NET3.5)中最令人兴奋的特性。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)。

在这里我会讨论C#3.0中的一些新的语言特性和改进,正是它们使得LINQ变得如此强大,让你可以写出这样的代码:

var result = from c in Customers
             where c.City == Boston"
             orderby c.LastName descending
             select new { c.FirstName, c.LastName, c.Address };
记住,如果你想要使用LINQ,你需要安装Visual Studio 2008(.NET3.5)。

新的语言特性

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类。假设我们想要这个类的一个实例,我们会建立对象并设置它的属性,代码会是这样子的:

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<int,bool> IsPositive = delegate(int num) {
                                   return num > 0;
                               };
我们也可以使用新的Lambda表达式来写:

MyDeleg<int,bool> 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}___FCKpd___12quot; );
        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.Linq和System.Xml.Linq命名空间中。

参考和资源

"New Orcas Language Feature" Series by Scott Guthrie: 讲解LINQ的系列文章
LINQ Resources: Daniel Moth 写的日志
MSDN Magazine (June 2007): 一篇介绍 C# 3.0 和 LINQ 的文章
Visual Studio Orcas Samples: C#/VB LINQ 示例
Future Versions: C# 3.0
The LINQ Project: LINQ 项目主页 
文章出处:http://www.diybl.com/course/4_webprogram/asp.net/netjs/2008530/118056_2.html


文章出处:http://www.diybl.com/course/4_webprogram/asp.net/netjs/2008530/118056.html