从LINQ的角度看待C#3.0的新功能

发表于:2008-05-07来源:作者:点击数: 标签:LinqLINQ角度功能
大约20天前曾经写了一篇C#3.0学习笔记,今天读了MSDN关于LINQ项目的介绍,很有收获。 文章(“LINQ 项目-.NET 语言集成查询”)是Dan Box和Anders Hejlsberg写的,内容很多,而且不是以C#3.0的新功能为主线组织的,只在“支持 LINQ 项目的语言功能”节中从LIN
大约20天前曾经写了一篇C#3.0学习笔记,今天读了MSDN关于LINQ项目的介绍,很有收获。

  文章(“LINQ 项目-.NET 语言集成查询”)是Dan Box和Anders Hejlsberg写的,内容很多,而且不是以C#3.0的新功能为主线组织的,只在“支持 LINQ 项目的语言功能”节中从LINQ的需求角度点评了那些新功能。现在在原笔记的基础上附上文中的这些点评,后补充的文字用粗体以示区别。

  实际上有一篇主题更明确、更易懂的文章:LINQ 的演变及其对 C# 设计的影响,从对C#的期望出发,逐渐揭示了3.0中主要新特性的登台理由。

  在探究当前的和下一代技术时,明显可以看出,有关编程技术的下一个难题是降低访问和集成特定信息(这些信息不是使用 OO 技术进行原始定义的)的复杂性。非 OO 信息的两个最常见源是关系数据库和 XML。

  对于 LINQ 项目,我们采取了更为普通的方法,并向 .NET Framework 中添加了适用于所有信息源(而不只是关系数据或 XML 数据)的通用查询工具,而不是在编程语言和运行库中添加相关功能或特定于 XML 的功能。该工具名为 .NET 语言集成查询 (LINQ)。
  1. Implicitly typed local variables

  In an implicitly typed local variable declaration, the type of the local variable being declared is inferred from the expression used to initialize the variable.

  C#始终是强类型的,var关键字做的只是表面文章。无论如何都要保证,编译器仅根据当前的声明语句(实际上可供它参考的信息就是初始化表达式)就能推断变量类型。

  要使变量能够引用匿名类型的实例,同时仍然从静态类型获益,C# 引入了 var 关键字,以便用于替换局部变量声明的类型名称。

  var 关键字方便用于其类型名称有意义的变量,但对于引用匿名类型实例的变量而言是必需的。
  2. Extension methods

  Extension methods are static methods that can be invoked using instance method syntax. In effect, extension methods make it possible to extend existing types and constructed types with additional methods.

  之前,我们为类定义一个实例方法,编译器将之实现为一个静态函数,它以当前类的实例为第一个参数。现在,我们在静态类中定义这么一个静态方法,它的第一个参数前有this修饰符,于是编译器假装它是第一个参数所在类型的实例方法。

  联想到曾有人用C语言写出“非常面向对象”的代码,再一次觉得高级的语言功能说到底就是编译器玩的把戏。

  这个功能允许你在不修改类的定义的前提下,为它增添新的方法。就效果而言,它多少体现了基于原型的面向对象语言(prototype-based object-oriented language)的特点。比如在javascript中,可以写这样的代码:
//定义一个函数,函数内部使用了this关键字。 function hi() { alert("Hi there! this is " + this + "."); } String.prototype.sayHi= hi; //为String对象添加sayHi方法,并指定其实现由函数hi定义。var p= new String("pzy"); p.sayHi();
  不同之处在于,C#是根据参数类型自动把静态函数关联到类型的实例方法上的,而在javascript中需要显式地指定对象原型的属性。

  标准查询操作符将定义为 System.Query.Sequence 类型的扩展方法。……希望将标准查询操作符替换为特定类型的用户可以:(a) 使用兼容的签名在特定类型上定义他们自己的同名方法,或者 (b) 定义可扩展特定类型的新的同名扩展方法。
3. Lambda expressions

  Lambda expressions provide a more concise, functional syntax for writing anonymous methods.

  考虑定义一个Foreach函数。在C#中,代码可能是这样的:
delegate void Action(A a);static void Foreach(IEnumerable collection, Action action) { foreach (T t in collection) action(t); } string[] words = new string[] { "Are", "You", "OK", "?" }; //C#2.0: Foreach(words, delegate(string w) { Console.WriteLine(w); }); //C#3.0: Foreach(words, w=> Console.WriteLine(w));
  呵呵,C#2.0中定义匿名方法的语法与javascript的几乎一样,而C#3.0的语法则简短到骇人的程度了!

  基于 λ 表达式的概念而生成的查询工具为开发人员提供了一种编写函数的简便方法,这些函数可以作为后续计算的参数进行传递。
  4. Object and collection initializers

  An object creation expression (§7.5.10.1) may include an object or collection initializer which initializes the members of the newly created object or the elements of the newly created collection.

  这么直观的语法早该有了,简便程度上直逼javascript啊。不过javascript走得更远,它的数组不但可以用元素列表初始化,甚至还有字面值(literal value),比如

原文转自:http://www.ltesting.net