C# Version 3.0 Specification

来源:互联网 发布:java共享内存 编辑:程序博客网 时间:2024/06/16 10:58

 

 

 

 

 

 

 

 

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 ofMicrosoft

Corporation inthe U.S.A.and/or other countries/regions.

 

Other product andcompany names mentioned hereinmay 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

 

始化器明一个名类回这的实个匿是一(namelessclass)(译者:参考 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  contacts  =  new[]  {

new  {

Name  =  "Chris  Smith",

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

},

new  {

Name  =  "Bob  Harris",

PhoneNumbers  =  new[]  {  "650-555-0199"  }

}

};

26.7  

为查询供了一类似于关系分层的查询( SQL XQuery)语言集(:

intergrated 或译整合)语法。

 

query-expression:

from-clause   query-body

 

from-clause:

from   from-generators

 

from-generators:

from-generator

from-generators  ,   from-generator

 

from-generator:

identifier   in   expression

 

query-body:

from-or-where-clausesopt     orderby-clauseopt      select-or-group-clause   into-clauseopt

 

from-or-where-clauses:

from-or-where-clause

from-or-where-clauses   from-or-where-clause

 

from-or-where-clause:

from-clausewhere-clause

 

where-clause:

where   boolean-expression

 

orderby-clause:

orderby   ordering-clauses

 

ordering-clauses:

ordering-clause

ordering-clauses   ,   ordering-clause

 

ordering-clause:

expression   ordering-directionopt

 

ordering-direction: ascending descending

 

 

 

 

 

 

16                                                                                                                          Copyright 2 Microsoft Corporation 2005. All Rights Reserved.


select-or-group-clause:

select-clause group-clause

 

select-clause:

select   expression

 

group-clause:

group   expression   by   expression

 

into-clause:

into   identifier   query-body

值(non-assignment-expression表达式分类其定义出现§

from 开始,结束于 select group 头的 from 子句可以跟随 0 个或者更 from

where from 子句都是一产生器,它引入了一个迭代变量在序列上搜索;每个 where 滤器,从结果排除。最 select group 子句指定了依据迭代量得出结果 (shape)Select group 子句前面可有一个 orderby 明返回果的顺。最后 into 子句 通过把一条查询语句的结作为产进子的方式来拼查询。

式中,个产生 from 等价于单个产器的 from 子句。

26.7.1  查询表达 translation

C# 3.0 语言没有指查询表达式准确的执行语义。 C# 3.0 表达式(translate)成遵循查询 的多个法的调。特查询被转 Where, Select, SelectMany, OrderBy, OrderByDescending, ThenBy, ThenByDescending GroupBy 用,这方法有特 ,描述§。这些方法以是被查询对象的实例方法或者对象外部的扩展方法,它们实现了 询的执过程。

 

式到方调用的(translation)定或重决议执 证语法的正确但不生语 C#代码。查询达式的转换之后,产生的方法 规函数用被处,并能依出错如如不存比如 法是泛的而类推导败。

的转换过一系例子下。转换描述部分。

26.7.1.1 where 中的 where

 

from  c  in  customers

where  c.City  ==  "London"

select  c

代变量识符和 where 达式合 lambda 表达 Where

 

customers.

Where(c  =>  c.City  ==  "London")

26.7.1.2 select

例子示迭代变 select 通过转成方法用而的。

Select 择最内迭代变以外的东西

 

from  c  in  customers

where  c.City  ==  "London"

select  c.Name

 

 

 

 

Copyright 2 Microsoft Corporation 2005. All Rights Reserved.                                                                                                                         17


Overview of C# 3.0

 

 

lambda 表达式的 Select 方法的调用:

 

customers.

Where(c  =>  c.City  ==  "London").

Select(c  =>  c.Name)

26.7.1.3 group

group 子句:

 

from  c  in  customers

group  c.Name  by  c.Country

GroupBy 方法的调用

 

customers.

GroupBy(c  =>  c.Country,  c  =>  c.Name)

26.7.1.4 orderby

orderby 子句:

 

from  c  in  customers orderby  c.Name

select  new  {  c.Name,  c.Phone  }

OrderBy 方法的调用,或者如递减方定时 OrderByDescending 调用。

 

customers.

OrderBy(c  =>  c.Name).

Select(c  =>  new  {  c.Name,  c.Phone  })

orderby 子句中的第二个(secondary)次序

 

from  c  in  customers

orderby  c.Country,  c.Balance  descending

select  new  {  c.Name,  c.Country,  c.Balance  }

ThenBy ThenByDescending

 

customers.

OrderBy(c  =>  c.Country).

ThenByDescending(c  =>  c.Balance).

Select(c  =>  new  {  c.Name,  c.Country,  c.Balance  })

26.7.1.5 重产生器

 

from  c  in  customers

where  c.City  ==  "London"

from  o  in  c.Orders

where  o.OrderDate.Year  ==  2005

select  new  {  c.Name,  o.OrderID,  o.Total  }

产生器外,所的都 SelectMany 的调用,:

 

customers.

Where(c  =>  c.City  ==  "London").

SelectMany(c  =>

c.Orders.

Where(o  =>  o.OrderDate.Year  ==  2005).

Select(o  =>  new  {  c.Name,  o.OrderID,  o.Total  })

)

器与 orderby 子句结合

 

 

 

18                                                                                                                          Copyright 2 Microsoft Corporation 2005. All Rights Reserved.


from  c  in  customers,  o  in  c.Orders where  o.OrderDate.Year  ==  2005 orderby  o.Total  descending

select  new  {  c.Name,  o.OrderID,  o.Total  }

Select 被注入进来集排序表达(ordering expressions)列中的终结

 OrderBy 整个序OrderBy 之后,最终果从元组中提取出

 

customers. SelectMany(c  => c.Orders.

Where(o  =>  o.OrderDate.Year  ==  2005).

Select(o  =>  new  {  k1  =  o.Total,  v  =  new  {  c.Name,  o.OrderID,  o.Total  }  })

).

OrderByDescending(x  =>  x.k1).

Select(x  =>  x.v)

26.7.1.6 info

info 子句:

 

from  c  in  customers

group  c  by  c.Country  into  g

select  new  {  Country  =  g.Key,  CustCount  =  g.Group.Count()  }

询的一简单而方便法:

 

from  g  in

from  c  in  customers group  c  by  c.Country

select  new  {  Country  =  g.Key,  CustCount  =  g.Group.Count()  }

下:

 

customers.

GroupBy(c  =>  c.Country).

Select(g  =>  new  {  Country  =  g.Key,  CustCount  =  g.Group.Count()  })

26.7.2  查询表达式

模式建了一个法的类型现它查询。因表达 成方法用,类在如查询模式大的。例式的 例方法扩展方,因者具的调;并可以request

delegates ,因为 lambda 成这两

 

使用的支持查询表达式模式的泛型类型 C<T>(shape)泛型类被使用 的适当系,但非泛实现式同能的。

 

 

 

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

 

class  C<T>

{

public  C<T>  Where(Func<T,bool>  predicate);

 

public  C<S>  Select<S>(Func<T,S>  selector);

 

public  C<S>  SelectMany<S>(Func<T,C<S>>  selector);

 

public  O<T>  OrderBy<K>(Func<T,K>  keyExpr);

 

public  O<T>  OrderByDescending<K>(Func<T,K>  keyExpr);

 

public  C<G<K,T>>  GroupBy<K>(Func<T,K>  keyExpr);

 

 

 

 

Copyright 2 Microsoft Corporation 2005. All Rights Reserved.                                                                                                                         19


Overview of C# 3.0

 

 

public  C<G<K,E>>  GroupBy<K,E>(Func<T,K>  keyExpr,  Func<T,E>  elemExpr);

}

 

class  O<T>  :  C<T>

{

public  O<T>  ThenBy<K>(Func<T,K>  keySelector);

 

public  O<T>  ThenByDescending<K>(Func<T,K>  keySelector);

}

 

class  G<K,T>

{

public  K  Key  {  get;  }

 

public  C<T>  Group  {  get;  }

}

使用泛型 delegate Func<A, R>,但是同样可参数和返回型中的相同使用其

 delegate 式树类

C<T> O<T>之间的关系证仅在 OrderBy OrderByDescending 的返回结 ThenBy

ThenByDescending 用的。请注荐的 GroupBy 外形是组的序,每个 Key Group(property)

操作符 单独的范中任意实现了 System.Collections.Generic.IEnumerable<T>

查询操作符式的实

26.7.3  正式的转换

通过依重复应下述行处个转用,出现模式止。

OrderBy ThenBy 调用的转换,如果对应的排序子句指定了一个递减方向的指示器,

OrderByDescending  ThenByDescending 就会产生。

·    into 子句的查询

 

q1    into  x  q2

 

from  x  in  (  q1    )  q2

·    生器的 from

 

from  g1    ,  g2    ,    gn

 

from  g1    from  g2      from  gn

·    where 子句的 form 子句

 

from  x  in  e  where  f

 

from  x  in  (  e  )  .  Where  (  x  =>  f  )

·    from orderby select 子句的查询表达式

 

from  x1    in  e1    from  x2    in  e2      orderby  k1    ,  k2      select  v

 

 

 

20                                                                                                                          Copyright 2 Microsoft Corporation 2005. All Rights Reserved.


(  from  x1    in  e1    from  x2    in  e2    

 

select  new  {  k1  =  k1    ,  k2  =  k2      ,  v  =  v  }  )

 

.  OrderBy  (  x  =>  x  .  k1  )  .  ThenBy  (  x  =>  x  .  k2  )  

 

.  Select  (  x  =>  x  .  v  )

·    from orderby group 询表达式

 

from  x1    in  e1    from  x2    in  e2      orderby  k1    ,  k2     group  v  by  g

 

(  from  x1    in  e1    from  x2    in  e2    

 

select  new  {  k1  =  k1    ,  k2  =  k2      ,  v  =  v  ,  g  =  g  }  )

 

.  OrderBy  (  x  =>  x  .  k1  )  .  ThenBy  (  x  =>  x  .  k2  )  

 

.  GroupBy  (  x  =>  x  .  g  ,  x  =>  x  .  v  )

·    from 和一个 select 查询表

 

from  x  in  e  from  x1    in  e1      select  v

 

(  e  )  .  SelectMany  (  x  =>  from  x1    in  e1      select  v  )

·    from 子句和一个 group 表达式

 

from  x  in  e  from  x1    in  e1      group  v  by  g

 

(  e  )  .  SelectMany  (  x  =>  from  x1    in  e1      group  v  by  g  )

·    from,没有 orderby select 子句的查询达式

 

from  x  in  e  select  v

 

(  e  )  .  Select  (  x  =>  v  )

v 是标识符 x 时,转换都简单的

 

 

 

(  e  )

·    from orderby,一个 group 子句的查询达式

 

from  x  in  e  group  v  by  g

 

(  e  )  .  GroupBy  (  x  =>  g  ,  x  =>  v  )

v 是标识符 x,转换是

 

(  e  )  .  GroupBy  (  x  =>  g  )

 

 

 

Copyright 2 Microsoft Corporation 2005. All Rights Reserved.                                                                                                                         21


Overview of C# 3.0

 

 

·    from orderby,一个 select 询表达式

 

from  x  in  e  orderby  k1    ,  k2      select  v

 

(  e  )  .  OrderBy  (  x  =>  k1    )  .  ThenBy  (  x  =>  k2    )    .  Select  (  x  =>  v  )

v 是标识符 x 时,翻译是单的。

 

(  e  )  .  OrderBy  (  x  =>  k1    )  .  ThenBy  (  x  =>  k2    )  

·    from orderby,一个 group 子句的查询达式

 

from  x  in  e  orderby  k1    ,  k2      group  v  by  g

 

(  e  )  .  OrderBy  (  x  =>  k1    )  .  ThenBy  (  x  =>  k2    )  

 

.  GroupBy  (  x  =>  g  ,  x  =>  v  )

v x

 

(  e  )  .  OrderBy  (  x  =>  k1    )  .  ThenBy  (  x  =>  k2    )    .  GroupBy  (  x  =>  g  )

26.8  Expression trees

lambda 表达式表示数据结构而不是可执行代码。可转型到 delegate 类型 D lambda 转型到 System.Query.Expression<D>,到 delegate lambda 的转型

表达式实例的码产(emit) lambda 表达式的高内存数据表示,并生成表达 构,且使其显式

 

表示一个 lambda 即作为执行代,又作为表达式树。因为存在到 Func<int,int> 在到 Expression<Func<int,int>>

 

Func<int,int>  f  =  x  =>  x  +  1;                            //  Code

 

Expression<Func<int,int>>  e  =  x  =>  x  +  1;       //  Data

数之后delegate f 引用返回 x+1 表达式树 e 引用描述表达 x+1 的数据结

注意:

式树的在单范中规范在 PDC 2005 技术议上不存

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

22                                                                                                                          Copyright 2 Microsoft Corporation 2005. All Rights Reserved.

原创粉丝点击