zoukankan      html  css  js  c++  java
  • 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  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-clause where-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.

  • 相关阅读:
    你所选择的栏目与当前模型不相符请选择白色的选
    DEDECMS首页调用图片集里的多张图片
    dedecms内容页调用图片集文档的图集图片
    Sublime Text 使用介绍、全套快捷键及插件推荐
    基于Nutch+Hadoop+Hbase+ElasticSearch的网络爬虫及搜索引擎
    nutch
    ant安装
    selenium经过WebDriverWait实现ajax测试
    查看当前android设备已安装的第三方包
    批处理学习总结之常用符号
  • 原文地址:https://www.cnblogs.com/zhouyinhui/p/731574.html
Copyright © 2011-2022 走看看