乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      C# 3.0 特性預(yù)覽

       昵稱10504424 2013-02-28
      聲明:本文主要是根據(jù)微軟《C# 3.0 Specification》文檔翻譯而成(本文內(nèi)容并非完整按照該文檔進(jìn)行編排),并對(duì)msdn相關(guān)文檔中的資料進(jìn)行整理而成。若有翻譯不妥之處,懇請(qǐng)指正。
          
          閱讀本文前,需要了解:
          1、C# 3.0代號(hào)“Orcas”,是基于C# 2.0的擴(kuò)展。提供了多種具有更高層次功能的類庫。這些擴(kuò)展允許構(gòu)造組合(compositioanl)API來實(shí)現(xiàn)具有同關(guān)系型數(shù)據(jù)庫及XML等領(lǐng)域相等效能的表達(dá)效力。
          2、LINQ項(xiàng)目可以看作是一個(gè)未來技術(shù)的演示項(xiàng)目,可以從MSDN網(wǎng)站上下載預(yù)覽包。LINQ項(xiàng)目旨在擴(kuò)展C#及VB.NET在語法上對(duì)語言集成查詢的支持。借助這些特性,我們可以用類似SQL或者XQuery之類的語句進(jìn)行代碼編寫。LINQ項(xiàng)目的內(nèi)容不單獨(dú)介紹,因?yàn)樗鼘?duì)于C#中的特性主要就是C# 3.0中的語言集成查詢特性。
          3、寫這篇文章的目的很簡單,就是希望有興趣的朋友可以開始3.0的探索了,這樣當(dāng)3.0的編譯器出臺(tái)時(shí)不至于再趕時(shí)間學(xué)習(xí)。并不建議初學(xué)者花費(fèi)精力來掌握本文內(nèi)容,了解一下發(fā)展概況即可,否則很容易導(dǎo)致兩頭都搞不好。況且這并不是最基礎(chǔ)的內(nèi)容。
          4、本文內(nèi)容僅基于預(yù)覽版本內(nèi)容(PDC 2005 Technology Preview),并非最終版本。C# 3.0完成后,有可能會(huì)增加或者更改某些特性。預(yù)覽版本可能還不能支持C# 3.0中的某些內(nèi)容,對(duì)于這些內(nèi)容,將簡單介紹。
          5、本文旨在將新的特性展現(xiàn)出來,針對(duì)每個(gè)特性并不進(jìn)行深入的探討,讀者如果有興趣可以自行參閱相關(guān)資料。
          
          那么,我們就開始吧。
          
          C# 3.0的擴(kuò)展特性主要包括以下幾點(diǎn),我們?cè)诤竺嬉矔?huì)按照這個(gè)順序進(jìn)行介紹:
          1、隱式局部變量(implicitly typed local variables),通過初始化該局部變量的表達(dá)式自動(dòng)推斷出該變量的類型。
          2、擴(kuò)展方法(extention methods),可以利用附加方法拓展已經(jīng)存在的類型和構(gòu)造類型。
          3、Lambda表達(dá)式(lambda expressions),匿名方法的革新,能夠提供更好的類型推導(dǎo)以及到委托類型和表達(dá)式樹的轉(zhuǎn)換。
          4、表達(dá)式樹(expression trees),允許Lambda表達(dá)式以數(shù)據(jù)(表達(dá)式樹)的形式存在,而不是代碼(委托)。
          5、對(duì)象初始化器(object initializer),簡化了對(duì)象的構(gòu)造和初始化。
          6、匿名類型(anonymouse types),由對(duì)象初始化器自動(dòng)推斷和生成的元組類型。
          7、隱式數(shù)組(implicitly typed array),一種數(shù)組創(chuàng)建和初始化的形式,可以從數(shù)組初始化器推導(dǎo)出數(shù)組的元素類型。
          8、查詢表達(dá)式(query expressions),提供語言集成查詢的語法,使得在編程中可以使用類似關(guān)系型(如SQL)以及層次(如XQuery)查詢語言的代碼。   
                
          
      一、隱式局部變量
          在以前,如果我們要聲明局部變量,比如:
          int i = 5;
          string str = "test";
          int[] numberss = new int[]{1, 2, 3);
          ArrayList list = new ArrayList();
          在C# 3.0,完全可以等價(jià)為
          var i = 5;
          var str = "test";
          var numberss = new int[]{1, 2, 3);
          var list = new ArrayList();
          我們可以看到,用一個(gè)簡單的var就可以代替這么些類型(懷念Pascal中~~~)。因?yàn)?,我們往往只要關(guān)注后面的賦值表達(dá)式即可推斷出變量的類型,在這里也是如此。
          
          不過呢,自然要有運(yùn)用條件:
          1、出于向后兼容的考慮,如果作用域中出現(xiàn)一個(gè)叫做var的類型,那么會(huì)優(yōu)先使用var類型來聲明該變量而不再推斷表達(dá)式的類型。
          2、聲明隱式變量的同時(shí)需要初始化。而初始化需要一個(gè)表達(dá)式,且該表達(dá)式不能是單獨(dú)的對(duì)象或者集合初始化器,但可以是包含對(duì)象或者集合初始化器的new表達(dá)式。如var x;和var x = {1 ,2 ,3};都是錯(cuò)誤的。
          3、表達(dá)式的編譯時(shí)類型不能為空類型(null)。如var x = null;就是錯(cuò)誤的。
          4、如果隱式變量的聲明中包含多個(gè)聲明符,那么這些聲明符必須具備同樣的編譯時(shí)類型。
          
          此外,for語句中的初始化部分以及using語句的資源聲明中,都可以使用隱式變量。同樣的,使用foreach迭代也可以利用隱式變量:
          int[] numbers = {1, 2, 3, 4};
          foreach(var n in numbers) Console.WriteLine(n);
         
          
      二、擴(kuò)展方法
          通過在方法的第一個(gè)參數(shù)中用this關(guān)鍵字修飾,即可聲明一個(gè)擴(kuò)展方法。但是,擴(kuò)展方法必須聲明于靜態(tài)類中。
          namespace TestSpace{
              public static class Extensions{
                  public static int ToInt32(this string s){
                      return int.Parse(s);
                  }
              }
          }
          這些擴(kuò)展方法享有普通靜態(tài)方法等同的功能。此外,只要引入了擴(kuò)展方法,我們就可以通過普通的實(shí)例方法調(diào)用語法來調(diào)用它們。
          
          那么,我們現(xiàn)在就介紹如何引入擴(kuò)展方法。
          相信大家對(duì)于using很熟悉了吧。using System;相當(dāng)于引入了System命名空間中的所有類型。不過呢,using在這里的意義可不單單是引入了類型,還引入了屬于該命名空間下的擴(kuò)展方法。擴(kuò)展方法被引入之后,擴(kuò)展方法中的第一個(gè)參數(shù)(即被this修飾的參數(shù))的類型便多了這么一個(gè)附加方法。并且該附加方法的優(yōu)先級(jí)比該類型的同名實(shí)例方法要低。比如要使用上例中的擴(kuò)展方法,先引入:using TestSpace;然后可以這樣調(diào)用:
          string str = "1234";
          int re = str.ToInt32();
          //上式等價(jià)于int re = Extentions.ToInt32(s);
          
          經(jīng)過這兩個(gè)例子,我們可以看出:
          1、擴(kuò)展方法必須聲明在靜態(tài)類中(這樣也能保證自身是靜態(tài)方法)。
          2、擴(kuò)展方法聲明時(shí)至少有一個(gè)參數(shù),即要附加的實(shí)例類型,并且要用this來修飾。
          3、擴(kuò)展方法在作為附加方法調(diào)用時(shí)必然成為實(shí)例方法。
          4、擴(kuò)展方法在作為附加方法調(diào)用時(shí)的優(yōu)先級(jí)比同名的實(shí)例方法要低。即編譯器默認(rèn)調(diào)用實(shí)例類型的原有方法,如果找不到澤調(diào)用擴(kuò)展方法。    
             
             
      三、Lambda表達(dá)式
          通過C# 2.0帶來的匿名方法,我們已經(jīng)發(fā)現(xiàn)了簡化代碼的一種方法。但是,這樣的做法仍然有些冗長且具有強(qiáng)制性,所以C# 3.0中又引入了Lambda表達(dá)式。
          
          Lambda表達(dá)式寫成參數(shù)列表形式,后面緊跟“=>”符號(hào),再跟上一個(gè)表達(dá)式或者代碼塊。只要看一下后面給出的例子,Lambda表達(dá)式的寫法就很容易掌握,所以這里不再給出完整的Lambda表達(dá)式定義式。
          并且,Lambda表達(dá)式中的參數(shù)可以是顯式,也可以是隱式的。顯式參數(shù)列表中參數(shù)類型是顯式指定的,而隱式參數(shù)列表中的參數(shù)類型會(huì)根據(jù)上下文而定(特別地,當(dāng)Lambda表達(dá)式轉(zhuǎn)換為兼容委托時(shí),由這個(gè)委托提供參數(shù)的具體類型)。
          此外,如果參數(shù)列表中只有一個(gè)隱式的參數(shù),那么圓括號(hào)可以省略,如:
          ( param ) => expression
          可簡化為
          param => expression
          
          那么,我們來看一下例子:
          (int x) => x + 1    //顯式參數(shù)列表
          x => x + 1        //隱式參數(shù)列表,由于只有一個(gè)隱式的參數(shù),所以沒有圓括號(hào)
          () => Console.WriteLine("Hello")        //無參數(shù)
          (int x, int y) => x + y    //兩個(gè)顯式參數(shù)
          x => { return x + 1; }    /*帶有代碼塊的隱式Lambda表達(dá)式。但該功能目前尚不被PDC 2005 Technology Preview所支持,所以下文中將不再討論該功能的運(yùn)用。*/
          相信大家看完這些例子以后就知道怎么使用Lambda表達(dá)式了吧(注意:這里說的只是表達(dá)式,僅是語句的一部分,相信細(xì)心的同志們已經(jīng)發(fā)現(xiàn)例子中沒有結(jié)尾分號(hào)了吧)。
          然后我們看一下將Lambda表達(dá)式融入語句中的示例,同時(shí)給出用匿名方法實(shí)現(xiàn)的等效做法來作對(duì)比(其中利用Func泛型委托):
          //sample 1
          Func<int, int> add = x => x + 1;    //隱式表達(dá)式
          //等價(jià)于
          Func<int, int> add =
              delegate(int x){
                  return x + 1;
              };
          
          //sample 2
          Func<string, bool> filter = s => s == "123";    //隱式表達(dá)式
          //等價(jià)于
          Func<string, bool> filter =
              delegate(string s){
                  return s == "123";
              };
          由此可以看出,Lambda表達(dá)式簡化了的確不少。更重要的是,它可以將一段匿名方法簡化為一個(gè)表達(dá)式,這樣就為了嵌套使用提供了保障,我在后面的其它部分中也會(huì)涉及到嵌套調(diào)用。
          
          
      四、表達(dá)式樹
          表達(dá)式樹并不是PDC 2005標(biāo)準(zhǔn)的一部分,這里將簡單闡述。
          表達(dá)式樹最根本的運(yùn)用就是System.Query.Expression<D>類型(有的材料上是System.Expressions.Expression<T>)。它為Lambda表達(dá)式提供了一個(gè)內(nèi)存中高效的數(shù)據(jù)表示形式。
          對(duì)于下面這個(gè)Lambda表達(dá)式:
          Func<int, int> f = x => x + 1;
          這是代碼(委托)形式。而
          Expression<Func<int, int>> e = x => x + 1;
          就是一個(gè)對(duì)表達(dá)式樹的引用。
          
          Lambda表達(dá)式可以直接執(zhí)行,如int re = f(1);
          但是表達(dá)式樹的引用不可以,即int re = e(1);是錯(cuò)誤的。
          
          那么如何運(yùn)用表達(dá)式樹呢?
          表達(dá)式樹可以看作是對(duì)表達(dá)式委托的結(jié)構(gòu)體現(xiàn)??纯聪旅孢@個(gè)例子(轉(zhuǎn)),估計(jì)就比較有些理解了:
          Expression<Func<int, boo>> filter = n => n < 5;
          BinaryExpression body = (BinaryExpression)filter.Body;
          ParameterExpression left = (ParameterExpression)body.Left;
          ConstantExpression right = (ConstantExpression)body.Right;
          Console.WriteLine("{0} {1} {2}", left.Name, body.NodeType, right.Value);
          表達(dá)式樹的這種數(shù)據(jù)形式在后面將要談到的數(shù)據(jù)查詢方面是一個(gè)很好的輔助工具。   
             
             
      五、對(duì)象和集合初始化器
          使用對(duì)象初始化表達(dá)式可以方便地初始化一個(gè)或者多個(gè)對(duì)象的屬性或者域。
          初始化表達(dá)式由“{”和“}”進(jìn)行封閉,同時(shí)內(nèi)部的成員初始化器用“,”進(jìn)行分隔。成員初始化器包括成員名稱、“=”和初始化的值。
          比如,對(duì)于類Dog:
          public class Dog{
              private string name;
              private int age;
              public string Name{
                  get{
                      return name;
                  }
                  set{
                      name=value;
                  }
              }
              public int Age{
                  get{
                      return age;
                  }
                  set{
                      age=value;
                  }
              }
          }
          這樣初始化:
          Dog dog = new Dog{
              Name = "Toddy", Age = 5
          };
          等價(jià)于
          Dog dog = new Dog();
          dog.Name = "Toddy";
          dog.Age = 5;
          當(dāng)然,嵌套的初始化也是允許的。
          
          同樣,集合初始化器使得集合可以像數(shù)組那樣初始化:
          List<int> list = new List<int>{1, 2, 3, 4};
          就這么簡單……
          
          
      六、匿名類型
          基于我們往往注重一個(gè)類型的結(jié)構(gòu)而不是名稱這個(gè)事實(shí),C# 3.0引入了匿名類型。
          隱式局部變量由編譯器自動(dòng)推測變量的類型,而匿名類型是讓編譯器自動(dòng)推測初始化表達(dá)式的類型。
          如第5節(jié)中的Dog類,我們其實(shí)也可以利用匿名類型來進(jìn)行初始化:
          var dog = new {Name = "Toddy", Age = 5};
          我們可以看到,上例中省略了類型名。
          有了匿名類型,我們無需了解這個(gè)類型叫做什么名字,只要符合這個(gè)結(jié)構(gòu)即可。
          
          
      七、隱式數(shù)組
          從前面的種種特性中可以看到,利用編譯器根據(jù)上下文推導(dǎo)來識(shí)別是C# 3.0的很多更新的基礎(chǔ),本節(jié)的隱式數(shù)組也是如此。
          隱式數(shù)組會(huì)自動(dòng)根據(jù)數(shù)組內(nèi)容來識(shí)別數(shù)組類型。
          我們以前這樣寫:
          int[] arr = new int[]{1,2,3};
          現(xiàn)在可以這樣:
          var arr = new[] {1,2,3};        //一定要有[]操作符,參見隱式局部變量的注意部分
          
          但是必須要注意:
          1、數(shù)組中的內(nèi)容均可以隱性轉(zhuǎn)換為某一類型。
          2、最終類型不可為null。       
                   
       
      八、查詢表達(dá)式
          個(gè)人認(rèn)為,C# 3.0這些新特性的引入,不單單是為了在某種程度上簡化平時(shí)的代碼開發(fā)量。更重要的是,它們?yōu)椴樵儽磉_(dá)式的方方面面都提供了良好的基礎(chǔ)。
          
          查詢表達(dá)式能夠在語言中使用類似SQL或者XPath/XQuery的語法進(jìn)行數(shù)據(jù)查詢。
          
          查詢表達(dá)式以from子句開始,以select或者group子句結(jié)束。大致組成順序是(可選):from子句、where子句、orderby子句、select子句和where子句以及into子句。
          
          看一個(gè)例子:
          string[] Weekdays = {
              "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
          };
          IEnumerable<string> enum_day =
              from day in Weekdays
              where day[0] == 'T'
              orderby day
              select day.ToUpper();
          foreach(var s in enum_day){
              Console.WriteLine(s);
          }
          你將會(huì)得到:
          THURSDAY
          TUESDAY
          
          如何?Amazing!
          
          那么,這樣的語句為什么能夠編譯呢?
          其實(shí),編譯器在編譯的時(shí)候進(jìn)行了轉(zhuǎn)換。上例中的enum_day的定義部分可轉(zhuǎn)換為:
          IEnumerable<string> enum_day = Weekdays
              .Where(day => day[0] == 'T')
              .OrderBy(day => day)
              .Select(day => day.ToUpper());
          這樣就清楚了吧(“括號(hào)里面的表達(dá)式什么?”不會(huì)吧,復(fù)習(xí)一下Lambda表達(dá)式吧)。
          
          當(dāng)然了,像SQL這樣的語句進(jìn)行嵌套、組合等可以產(chǎn)生很多有趣的查詢方法,C# 3.0中的查詢方式雖然僅是簡化版的SQL語法,不過經(jīng)過嵌套、組合等方法當(dāng)然可以形成復(fù)雜的表達(dá)式,這就靠大家今后鞏固了

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多