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                                                                                                                            Copyright 2 Microsoft Corporation 2005. All Rights Reserved.


·    以为 L 来,描如下:

 

样的参,将会过关联 P 的返回类型和 L 的推返回类论,并新的推被加入 论集。个过程重复直到进一论产

导和重决议的lambda 表达式 L 推导出的类决定于下面

·    L 一个表式,表式的类型就是推导 L 的返回类型。

 

·    L 一个语块,如语句块中 return 语句表达式集合(set)一个 中每个类型都可隐式转换成这个类就是推出的 L 型。(译者:如 {int, byte, double},则 double )

·    类型不 L 来。

 

lambda 表达式的类推导的例子,考虑声明 System.Query.Sequence 类中的 Select

 

namespace  System.Query

{

public  static  class  Sequence

{

public  static  IEnumerable<S>  Select<T,S>(

this  IEnumerable<T>  source,

Func<T,S>  selector)

{

foreach  (T  element  in  source)  yield  return  selector(element);

}

}

}

System.Query 间使用 using ,并且出一 Customer,带有类型为 string

Name, Select 方法可用作选择(list of )customers

 

List<Customer>  customers  =  GetCustomerList(); IEnumerable<string>  names  =  customers.Select(c  =>  c.Name);

Select 法调用过重写态方法调用处理:

 

IEnumerable<string>  names  =  Sequence.Select(customers,  c  =>  c.Name);

 

数未被式指明将会使型推导类。首先 customers 参数被关联到 source 推导 T Customer使用前面述的 lambda 表达式类型导过, c 类型 Customer c.Name 被关联到 selector 参数的返回型上, s string,这样,调就等价于

 

Sequence.Select<Customer,string>(customers,  (Customer  c)  =>  c.Name)

型是 IEnumerable<string>

示范了 lambda 型推导如何型信型函的参“流

 

 

 

static  Z  F<X,Y,Z>(X  value,  Func<X,Y>  f1,  Func<Y,Z>  f2)  {

return  f2(f1(value));

}

推导

 

double  seconds  =  F("1:15:30",  s  =>  TimeSpan.Parse(s),  t  =>  t.TotalSeconds);

 

 

 

 

Copyright 2 Microsoft Corporation 2005. All Rights Reserved.                                                                                                                           9


Overview of C# 3.0

 

 

下:首参数1:15:30值参数推导 X string lambda 表达式的参

s 导类型 string达式 TimeSpan.Parse(s) f1 类型上推导 Y System.TimeSpan。最后第 lambda 表达式的参数 t推导类型 System.TimeSpan t.ToTalSeconds f2 的返回类型,推导 Z double用的返类型就是 double

26.3.3  Overload resolution 重载

Lambda 表达式在某条件下影响重载决

要增加§7.4.2.3 lambda 表达式 L,为其推导的返回类型存在, delegate

 D1   D2 具有相同的数列表 L  D1 比从 L  D2 的隐式转型好;并 L 推导出  D1 型的隐转型比从 L 推导出的返类型到 D2 返回类型的式转型更好。如果这 真,两都不行。

例示了个规则效果。

 

class  ItemList<T>:  List<T>

{

public  int  Sum<T>(Func<T,int>  selector)  {

int  sum  =  0;

foreach  (T  item  in  this)  sum  +=  selector(item);

return  sum;

}

 

public  double  Sum<T>(Func<T,double>  selector)  {

double  sum  =  0;

foreach  (T  item  in  this)  sum  +=  selector(item);

return  sum;

}

}

 

ItemList<T>类有两个 Sum 每个方都有一个 selector 参数,方法列表项中提取值累 sum 以是 int double sum 同样可以是 int double

Sum 为例子于从 detail 列表中依次算和。

 

class  Detail

{

public  int  UnitCount;

public  double  UnitPrice;

...

}

 

void  ComputeSums()  {

ItemList<Detail>  orderDetails  =  GetOrderDetails(...);

int  totalUnits  =  orderDetails.Sum(d  =>  d.UnitCount);

double  orderTotal  =  orderDetails.Sum(d  =>  d.UnitPrice  *  d.UnitCount);

...

}

orderDetails.Sum ,两个 Sum 适用,是因为 lambda 表达式 d=>d.UnitCount 兼容于

Func<Detail,int> Func<Detail,double>然而,载决了第 Sum 是因为

 Func<Detail,in> Func<Detail,double>

orderDetails.Sum 用中,仅第二个 Sum 用,这因为 lambda 表达式

d=>d.UnitPrice*d.UnitCount 产生的类 double重载决为此调选择了第二个方法。

26.4  始化

(§7.5.10.1)可以包含一对象或集合初始化器,用于初始化新创建的对象的成员或新创 元素。

 

 

 

 

10                                                                                                                          Copyright 2 Microsoft Corporation 2005. All Rights Reserved.


object-creation-expression:

new   type   (   argument-listopt      )   object-or-collection-initializeropt

new   type   object-or-collection-initializer

 

object-or-collection-initializer:

object-initializer collection-initializer

 

达式可省略构(译者:或译构造器)(constructor)和封闭圆括号 个对象集合初化器构造数列闭的等价一个

或集合初始化器建表达的执行造函数由对象或集

始化器指定成员或元素初始化动

初始化不能引正被的对

26.4.1  Object initializers 象初

器指定个或多对象 值。

 

object-initializer:

{   member-initializer-listopt      }

{   member-initializer-list   ,   }

 

member-initializer-list:

member-initializer

member-initializer-list   ,   member-initializer

 

member-initializer:

identifier   =   initializer-value

 

initializer-value:

expression

object-or-collection-initializer

 

器由一列成员始化,封{}且由逗间隔成员器必须 始化的象的域属性,后=”  或者初始化

指定表方式处 号后指定一个对象初始化器器是对嵌对象初始象初中的

员的赋对待,不是属性值。的属用这

号后指定集合初始化器成员初始化器是对内嵌集合的初始化。初始化器中给定的元素被加进域

集合中而不是域或予新。域必须§要求的合类型。

求一个两个坐 point

 

 

 

public  class  Point

{

int  x,  y;

 

public  int  X  {  get  {  return  x;  }  set  {  x  =  value;  }  }

public  int  Y  {  get  {  return  y;  }  set  {  y  =  value;  }  }

}

Point 的实例可以创建和实例化如下:

 

 

 

Copyright 2 Microsoft Corporation 2005. All Rights Reserved.                                                                                                                         11


Overview of C# 3.0

 

 

var  a  =  new  Point  {  X  =  0,  Y  =  1  };

 

var  a  =  new  Point();

a.X  =  0;

a.Y  =  1;

类表示两个 points 构成的 rectangle

 

public  class  Rectangle

{

Point  p1,  p2;

 

public  Point  P1  {  get  {  return  p1;  }  set  {  p1  =  value;  }  }

public  Point  P2  {  get  {  return  p2;  }  set  {  p2  =  value;  }  }

}

Rectangle 的实例可以创建和初始化如下:

 

var  r  =  new  Rectangle  {

P1  =  new  Point  {  X  =  0,  Y  =  1  },

P2  =  new  Point  {  X  =  2,  Y  =  3  }

};

 

var  r  =  new  Rectangle();

var  __p1  =  new  Point();

__p1.X  =  0;

__p1.Y  =  1;

r.P1  =  __p1;

var  __p2  =  new  Point();

__p2.X  =  2;

__p2.Y  =  3;

r.P2  =  __p2;

__p1 __p2 是临变量且不可见和不可访问

Rectangle 的构造函数配了两个内嵌的 Point 的实例

 

public  class  Rectangle

{

Point  p1  =  new  Point(); Point  p2  =  new  Point();

 

public  Point  P1  {  get  {  return  p1;  }  }

public  Point  P2  {  get  {  return  p2;  }  }

}

可被用初始化嵌的 Point 而不是予新的例值。

 

var  r  =  new  Rectangle  {

P1  =  {  X  =  0,  Y  =  1  },

P2  =  {  X  =  2,  Y  =  3  }

};

 

var  r  =  new  Rectangle();

r.P1.X  =  0; r.P1.Y  =  1; r.P2.X  =  2; r.P2.Y  =  3;

 

 

 

 

 

12                                                                                                                          Copyright 2 Microsoft Corporation 2005. All Rights Reserved.


26.4.2  集合初始化

器指定合的元

 

collection-initializer:

{   element-initializer-listopt      }

{   element-initializer-list   ,   }

 

element-initializer-list:

element-initializer

element-initializer-list   ,   element-initializer

 

element-initializer:

non-assignment-expression

 

器由一列元素始化,封 { } 以逗号隔。素初 个将被加进正被初始化的集合对象中元素。

创建表式的例,包个集化器:

 

List<int>  digits  =  new  List<int>  {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9  };

 

用了集合初始化器必须实现了正好个类型 T System.Collections.Generic.IConlection<T>必须存从每个素类 T 隐式转 件都不足,就生编误。始化个指依次 ICollection<T>.Add(T)

示一个字和电号码表的 contact

 

public  class  Contact

{

string  name;

List<string>  phoneNumbers  =  new  List<string>();

 

public  string  Name  {  get  {  return  name;  }  set  {  name  =  value;  }  }

 

public  List<string>  PhoneNumbers  {  get  {  return  phoneNumbers;  }  }

}

List<Contact>创建和例化如

 

var  contacts  =  new  List<Contact>  {

new  Contact  {

Name  =  "Chris  Smith",

PhoneNumbers  =  {  "206-555-0101",  "425-882-8080"  }

},

new  Contact  {

Name  =  "Bob  Harris",

PhoneNumbers  =  {  "650-555-0199"  }

}

};

于:

 

 

 

 

 

 

 

 

 

 

 

 

 

Copyright 2 Microsoft Corporation 2005. All Rights Reserved.                                                                                                                         13


Overview of C# 3.0

 

 

var  contacts  =  new  List<Contact>();

var  __c1  =  new  Contact();

__c1.Name  =  "Chris  Smith";

__c1.PhoneNumbers.Add("206-555-0101");

__c1.PhoneNumbers.Add("425-882-8080");

contacts.Add(__c1);

var  __c2  =  new  Contact();

__c2.Name  =  "Bob  Harris";

__c2.PhoneNumbers.Add("650-555-0199");

contacts.Add(__c2);

__c1 __c2 是临变量,可见,也不可访问。

26.5  

C# 3.0 允许 new 操作符与匿对象初始化器联用来创建一个匿名类型的对象

 

primary-no-array-creation-expression:

anonymous-object-creation-expression

 

anonymous-object-creation-expression:

new   anonymous-object-initializer

 

anonymous-object-initializer:

{   member-declarator-listopt      }

{   member-declarator-list   ,   }

 

member-declarator-list:

member-declarator

member-declarator-list   ,   member-declarator

 

member-declarator: simple-name member-access

identifier   =   expression

 

始化器明一个名类回这的实个匿是一(nameless class)(译者:参考 jjhou (named)接继承自 Object。匿名类型成员是 导自用于创建这个类型实的对象/。特别,匿名象初始化器具有如

 

new  {  p1    =  e1    ,  p2    =  e2    ,    pn    =  en    }

个如下式的匿类型

 

class  __Anonymous1

{

private  T1    f1    ;

private  T2

f2

;

 

 

private  Tn

fn

;

 

 

public

T1

p1

{

get

{

return

f1

;

}

set

{

f1

=

value

;

}

}

 

public

T2

p2

{

get

{

return

f2

;

}

set

{

f2

=

value

;

}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

public

T1

p1

{

get

{

return

f1

;

}

set

{

f1

=

value

;

}

}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 Tx 达式 ex 的类型。匿对象初始化器中的表达式是 null 编译期误。

 

 

14                                                                                                                          Copyright 2 Microsoft Corporation 2005. All Rights Reserved.


名字是编译器动产在程中不用。

 

序中,相同顺指定列相和类个匿初始会产 例。(个定义含了次序为它环境可观要的比如 reflection

 

var  p1  =  new  {  Name  =  "Lawnmower",  Price  =  495.00  };

var  p2  =  new  {  Name  =  "Shovel",  Price  =  26.95  };

p1  =  p2;

赋值是行的, p1 p2 具有同的匿类型。

 

可以缩成简单(§7.5.2)员访(§7.5.4)。这称投射初始化(projection initializer),是具备相同名字属声明和速记式。

 

identifier                                              expr  .  identifier

下面:

 

identifer  =  identifier                        identifier  =  expr  .  identifier

 

射初始器中identifier 被赋予的值属性,投射始化投射 值的名

26.6  Implicitly typed arrarys

组创建(§7.5.10.2)的语法用以持隐型数组创建表达式

 

array-creation-expression:

new   [   ]   array-initializer

 

创建表式中,组实型推组初中元型。,数 类型形的类型(set),必须包含一个这样类型,个类隐式它,并 不是 null ,这个型的数就被。如推导准确,或者 型是空 null 编译器误就会现。

数组创表达式例子:

 

var  a  =  new[]  {  1,  10,  100,  1000  };        //  int[]

 

var  b  =  new[]  {  1,  1.5,  2,  2.5  };              //  double[] var  c  =  new[]  {  "hello",  null,  "world  };              //  string[] var  d  =  new[]  {  1,  "one",  2,  "two"  };                       //  Error

达式导编译器误, int string 都不能隐方。显数组达式 使用:例指定类 object[],其中个元素以被转型到一个公共基类型,这个 推导出元素类

建表达可以与名对化器使用来名类据结如:

 

 

 

 

 

 

 

 

 

 

 

Copyright 2 Microsoft Corporation 2005. All Rights Reserved.                                                                                                                         15


Overview of C# 3.0

 

 

var  con