C# Version 3.0 Specification

 

 

 

 

 

 

 

 

C# Version 3.0 Specification

 

September 2005

 

翻译: 邱龙斌 <qiu_lb (at) hotmail.com>

 

2005-09-15

 

 

 

得益于互联网的开放性和专业人员的共享精神,过去几年里我在网络上搜索到很多重要的参考 资料和电子文档。在此对大家的奉献性的工作表示感谢。

 

近日无意中发现了 Microsoft LINQ 项目,这个项目是用来试验 C#未来版本也就是 3.0 版本 的新功能的。有兴趣的朋友可以到 LINQ 项目主页去看看,上面有 C#  3.0  LINQ 的介绍、示 例代码。http://msdn.microsoft.com/netframework/future/linq/

 

本人使用 c++多年,深知语言核心的稳定和程序库的激进同样重要。对 c++而言 boost 提供了许 多库扩展方面的最佳实践,比如 boost.python,boost.function,boost.lambda 等。新的 c++0x 标准提案中提到在语言核心层直接支持 concept model 的概念,从而在编译期进行 concept

 model 的检查,就类型约束这点,我知道 c#2.0 泛型是用 where 表示泛型类型参数的约束的。

 

C#语言核心,近年来动作很大,继 2.0 加入泛型、匿名方法、迭代器、不完整类型、Nullable 类型之后,3.0 更是加入了一些引人注目的新特性。感慨之余,开发人员又要继续学习了;同 时开始担心例如 Mono,DotGnu 等开源.Net 项目。

 

浏览了一下 C#  3.0  Specification,感觉 C#有越来越动态化的倾向,数据查询方面也更直接。 花了点时间翻译成中文,希望对有需要的朋友有用。翻译错误再所难免,有问题的朋友可以跟 我联系,讨论本文的翻译问题。

声明:本译文不可用于商业目的流传,  Microsoft 可能有异议。

 

 

 

 

 

Notice

 

© 2005 Microsoft Corporation. All rights reserved.

 

Microsoft, Windows, Visual Basic, Visual C#, and Visual C++ are either registered trademarks or trademarks of Microsoft

Corporation in the U.S.A. and/or other countries/regions.

 

Other product and company names mentioned herein may be the trademarks of their respective owners.

 

 

 

 

 

 

 

 

 

 

 

 

 

 
Copyright 2 Microsoft Corporation 2005. All Rights Reserved.


Overview of C# 3.0

 

 

26.C# 3.0 概述..................... ............. .............. ............. .............. .............. ............. .............. ............. .............. .......3

26.1 隐型局部变(implicitly typed local variable)...........................................................................................3

26.2 扩展方.......................................................................................................................................................4

26.2.1 声明扩展方........................................................................................................................................4

26.2.2 导入扩展方........................................................................................................................................4

26.2.3 扩展方法调........................................................................................................................................5

26.3Lambda 表达.............................................................................................................................................6

26.3.1Lambda 表达式转...............................................................................................................................7

26.3.2 类型推................................................................................................................................................8

26.3.3Overload resolution ..............................................................................................................10

26.4 对象和集合始化.................................................................................................................................10

26.4.1Object initializers 对象初始化.........................................................................................................11

26.4.2 集合初始化......................................................................................................................................13

26.5 匿名类.....................................................................................................................................................14

26.6 隐型数组Implicitly typed arrarys.......................................................................................................15

26.7 查询表达.................................................................................................................................................16

26.7.1 查询表达式 translation........................................................................................................................17

26.7.1.1where .....................................................................................................................................17

26.7.1.2select ......................................................................................................................................17

26.7.1.3group ......................................................................................................................................18

26.7.1.4orderby ...................................................................................................................................18

26.7.1.5 生器...................................................................................................................................18

26.7.1.6info .........................................................................................................................................19

26.7.2 查询表达式..................................................................................................................................19

26.7.3 正式的转换..................................................................................................................................20

26.8 表达式树Expression trees..................................................................................................................22

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ii                                                                                                                            Copyright 2 Microsoft Corporation 2005. All Rights Reserved.


26.C# 3.0 

 

 

 

 

 

C# 3.0 (“C# (Orcas)”) 个构建在 C# 2.0 扩展,来支和使级的 (functional 或译:泛)类库。这些展允许 (compositional)APIs 这些 APIs 关系数据

 XML 查询语具有同的表力。

·    局部变量部变量类型化它达式来。

·    方法,使得使用附加(additional)展已存的类造类可能。

·    Lambda ,是匿名方的演进,可提供改良的类型推导和 dalegate 达式树转换。

·    初始化器对象的造和

·    类型,是从对象初始化器动推导的元(tuple)类型。

·    数组,数组创建和初始化形式,组初推导的元

·    表达于关系型和层次化查询语言(比如 SQL XQuery提供一个语集成

(intergrated)法。

·    式树,允许 lambda 为数(式树)而不是代(delegate) 些特征技术概。文 C#语言规范 1.2§1-§18 C#规范 2.0§19-§25

都在 C#页上(http://msdn.microsoft.com/vcsharp/language)

26.1  (implicitly typed local variable)

变量声中,正声明变量从初个变达式来。

指明 var ,并且范围(scope)中没有 var 类型存,这个明就称

声明

 

var  i  =  5;

var  s  =  "Hello";

var  d  =  1.0;

var  numbers  =  new  int[]  {1,  2,  3};

var  orders  =  new  Dictionary<int,Order>();

局部变声明精地等面的(explicitly typed)

 

int  i  =  5;

string  s  =  "Hello";

double  d  =  1.0;

int[]  numbers  =  new  int[]  {1,  2,  3};

Dictionary<int,Order>  orders  =  new  Dictionary<int,Order>();

量声明的局部量声(declarator)遵从下面这约束:

·    包含初化器。

 

·    须是一表达式初始能是合初始(§))它可以 一个 new

·    达式的译期类不可(null)

 

 

 

 

Copyright 2 Microsoft Corporation 2005. All Rights Reserved.                                                                                                                           3


Overview of C# 3.0

 

 

·    量声明含了多声明些声须具的编型。 不正确隐型局变量例子:

 

var  x;                                      //  Error,  no  initializer  to  infer  type  from

var  y  =  {1,  2,  3};       //  Error,  collection  initializer  not  permitted var  z  =  null;                            //  Error,  null  type  not  permitted

 

容的原,当局变量 var 而范围中又存 var 这个声 那个叫 var 的类型;然后,会产一个关(ambiguity)因为叫 var 的类型违 类名首母大写约定情形会出(译器实)

 

for 表达(§8.8.3) for 初始化(for-initializer) using 式的资源获(resource-acquisition)作为 部变量明。同foreach 表达(§8.8.4)迭代变可以声明为个隐型局部变量, 隐型局变量的类型正被(enumerated)元素的型。子:

 

int[]  numbers  =  {  1,  3,  5,  7,  9  };

foreach  (var  n  in  numbers)  Console.WriteLine(n);

n 推导为 numbers 的元素类型 int

26.2  

过使用例方法法调态方法。效果上,扩展方法使得用附加的方法扩展已 构造类成为可

注意

 

方法不发现功能例方限。些原荐保使用和例方 可能的使用。

种类的法,性、操作在被中,前并持。

26.2.1  声明扩展方

键字 this 修饰方法的一个参而声明的。展方法仅可声明在静态类中。 个扩展法的静类的子:

 

namespace  Acme.Utilities

{

public  static  class  Extensions

{

public  static  int  ToInt32(this   string  s)  {

return  Int32.Parse(s);

}

 

public  static  T[]  Slice<T>(this   T[]  source,  int  index,  int  count)  {

if  (index  <  0  ||  count  <  0  ||  source.Length    index  <  count)

throw  new  ArgumentException();

T[]  result  =  new  T[count];

Array.Copy(source,  index,  result,  0,  count);

return  result;

}

}

}

 

备所有规静态法的力。一旦,扩可以使例方

26.2.2  导入扩展方

法用 using-namespace-directives (§9.3.2)了导入含在间中using-

namespace-directives 名字空中所类中扩展实际导入方法作

 

 

 

4                                                                                                                            Copyright 2 Microsoft Corporation 2005. All Rights Reserved.


 

修饰的第一个参数类型上的附加方出现,并且比常规实例方法具有较低的优先权。比如 使 using-namespace-directive 上个例子中 Acme.Utilities  空间:

 

using  Acme.Utilities;

使在静态类 Extension 使方法语调用扩方法:

 

 

 

string  s  =  "1234";

int  i  =  s.ToInt32();                            //  Same  as  Extensions.ToInt32(s)

 

int[]  digits  =  {0,  1,  2,  3,  4,  5,  6,  7,  8,  9};

int[]  a  =  digits.Slice(4,  3);  //  Same  as  Extensions.Slice(digits,  4,  3)

26.2.3  扩展方法调

用的详规则表如下下调之一:

 

expr  .  identifier  (  )

 

expr  .  identifier  (  args  )

 

expr  .  identifier  <  typeargs  >  (  )

 

expr  .  identifier  <  typeargs  >  (  args  )

 

正常处过程发没有实例特别果这的候集是 理扩展法调用构造调用被分称如

 

identifier  (  expr  )

 

identifier  (  expr  ,  args  )

 

identifier  <  typeargs  >  (  expr  )

 

identifier  <  typeargs  >  (  expr  ,  args  )

 

式然后除非标 identifier 决议为:以靠近的封闭名字空间 以每个闭名字间声,并的编结束地试有可访问

,由 using-namespace-directives 的,指明为 identifier 字的扩展方法 重写的方法。第一 候选方集的方(method group)中的重的方法用。有的 选集,发生编期错

 

标表明例方法先于法,入进字空扩展先于 中的扩方法。如:

 

using  N1;

 

namespace  N1

{

public  static  class  E

{

public  static  void  F(this  object  obj,  int  i)  {  }

 

public  static  void  F(this  object  obj,  string  s)  {  }

}

}

 

class  A  {  }

 

 

 

 

 

 

Copyright 2 Microsoft Corporation 2005. All Rights Reserved.                                                                                                                           5


Overview of C# 3.0

 

 

class  B

{

public  void  F(int  i)  {  }

}

 

class  C

{

public  void  F(object  obj)  {  }

}

 

class  X

{

static  void  Test(A  a,  B  b,  C  c)  {

a.F(1);                             //  E.F(object,  int)

a.F("hello");             //  E.F(object,  string)

 

b.F(1);                             //  B.F(int)

b.F("hello");             //  E.F(object,  string)

 

c.F(1);                             //  C.F(object)

c.F("hello");             //  C.F(object)

}

}

中,B 先于第个扩C 优先于个扩展法。

26.3  Lambda

C# 2.0 引入了匿名方法,它许在 delegate (delegate value) (:delegate )方以内联

(in-line)个代码。当法提量函程语()(functional programming)的表达力时,实质上匿名方法是琐和制性Lambda 表达式提供 简练的数式语来写法。

Lambda 表达式写成一个后面  => 参数列=>一个表式或表句块。

 

expression:

assignment

non-assignment-expression

 

non-assignment-expression: conditional-expression lambda-expression

query-expression

 

lambda-expression:

(   lambda-parameter-listopt     )   =>   lambda-expression-body implicitly-typed-lambda-parameter   =>   lambda-expression-body

 

lambda-parameter-list:

explicitly-typed-lambda-parameter-list implicitly-typed-lambda-parameter-list

 

explicitly-typed-lambda-parameter-list explicitly-typed-lambda-parameter

explicitly-typed-lambda-parameter-list   ,   explicitly-typed-lambda-parameter

 

explicitly-typed-lambda-parameter:

parameter-modifieropt     type   identifier

 

 

 

 

 

 

6                                                                                                                            Copyright 2 Microsoft Corporation 2005. All Rights Reserved.


implicitly-typed-lambda-parameter-list implicitly-typed-lambda-parameter

implicitly-typed-lambda-parameter-list   ,   implicitly-typed-lambda-parameter

 

implicitly-typed-lambda-parameter:

identifier

 

lambda-expression-body:

expression block

 

Lambda 表达式的参数可以是型和隐在显列表个参型是定的在隐 中,参的类型由 lambda 现的语推导定地 lambda 型到一 delegate 时,delegate 供参数(§)

隐型参 lambda 表达式中,括号可以从参数列表中省略。换句话说,如下形式的

lambda 表达式

 

(  param  )  =>  expr

 

param  =>  expr

一些 lambda 表达式的例

 

x  =>  x  +  1                                             //  Implicitly  typed,  expression  body

 

x  =>  {  return  x  +  1;  }       //  Implicitly  typed,  statement  body

 

(int  x)  =>  x  +  1                           //  Explicitly  typed,  expression  body

 

(int  x)  =>  {  return  x  +  1;  }   //  Explicitly  typed,  statement  body

 

(x,  y)  =>  x  *  y                              //  Multiple  parameters

 

()  =>  Console.WriteLine()         //  No  parameters

 

C# 2.0 §21 匿名方规范用上了 lambda 表达式Lambda 表达式是匿方法 ,它提了如下加功

·    Lambda 表达式允许参数类型省略掉导,名方显式数类

·    Lambda 表达式体可以是一个达式或块,名方以是句块。

·    Lambda 表达式作为参数传递与类型(§26.3.3)

·    体的 Lambda 表达式可以被转换成达式(§26.8)

注意

 

PDC 2005 技术览编译不支持带有语句体的 lambda 。在要语句体的情况下,必须使用 C# 2.0 匿名方 法。

26.3.1  Lambda 达式

表达(anonymous-method-expression)类似lambda 是用特转换规作为(value) 。这个(value)但是可隐式转至一 delegate delegate D lambda 表达式 L 如果:

 

·    D L 有相数目的数。

 

 

 

Copyright 2 Microsoft Corporation 2005. All Rights Reserved.                                                                                                                           7


Overview of C# 3.0

 

 

·    L 参数列D 中的每个参数有着与应的 L 相同的型和

·    L 参数列D 不可有 ref out

 

·    D void 型,并且 L (body)是一个表达,当 L 参数被定为对 D 时,L 的体是一个许作为-(statement-expression(§8.6))

 

·    D void 并且 L 语句块 L 类型是给定为应的 D 参数的类 L 没有返语句的效语块。

 

·    D non-void 返回值并且 L 的体是一个达式,当 L 的每个参数型是被给定的相应于 D L 一个可隐式转 D 的有效达式。

 

·    D non-void 返回值并且 L 的体是一个句块,当 L 的每个参数型是被给定的相应于 D L 一个有的语句,语句有不可到(non-reachable)的终(end point)(者: 没有可到达终点),且每个终点的返回句指一个可以隐转换到 D 返回类

使用泛型 delegagte 类型 Func<A,R>表示一个带参数类型 A 和返回类型 R

 

delegate  R  Func<A,R>(A  arg);

下:

 

Func<int,int>  f1  =  x  =>  x  +  1;          //  Ok Func<int,double>  f2  =  x  =>  x  +  1;  //  Ok Func<double,int>  f3  =  x  =>  x  +  1;  //  Error

Lambda 表达式参数和返类型决定于 lambda 赋值的量的第一成功地 lambda 表达式到 delegate 类型 Func<int,int>,是因为当 x int x+1 是一个有效表达式 换到类型 int。同样第二赋值成功地转换 lambda 表达式到 delegate 类型 Func<int,double> x+1 值(类型 int)是隐式转 double 的。然而第三个赋值编译期因为当 x

doublex+1  double够隐式变到类型 int

26.3.2  类型

被调用不指明型参参数程试用中类型Lambda 表达式 与这个型推导程。

 

§20.6.4 中表述的那,类型推导首先为每个参数独立的发生。在初始阶段,不能从 lambda 表达式 任何东西。然而初始后,使用程的推导地, 足如下件为真参数推导生:

·    lambda 下面称为 L尚无推

·    类型,面称为 P回类型含有多个型参 delegate

 

·    P L 拥有同数目参数, P 中的每 L 应的参相同符, L 数列没有饰符。

 

·    P 类型包含方法类型参数或者包含仅仅一个方法类型参数,对这个参数已经产生一个相容的推导集

·    L 显型参列表,推导出的类型对于 P 中的方法类参数是可替换的时P 中的每

 L 参数相的类

 

·    L 隐型参列表,推导出的类型对于 P 中的方法类参数是可替代的,并且返回参数 给予 L 数,L 个有效达式块。

 

 

 

8