<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      LINQ之路 3:C# 3.0的語言功能(下)

      在LINQ介紹一篇中,我們已經看到了隱式類型變量var,擴展方法(Extension method)和Lambda表達式的身影。沒錯,他們正是LINQ技術的基石,是他們讓LINQ的實現成為可能,并且簡化了LINQ表達式的書寫。在這一篇中,我將和大家一一探討C#3.0在語言功能上所作的努力,包括:擴展方法、Lambda表達式和對象初始化器。 

       

      擴展方法

      下一個與LINQ密切相關的C# 3.0語言功能是擴展方法(Extension method)。在這之前,一旦一個類型被編譯進.NET程序集后,我們便不能再修改該類型的定義了。為該類型添加、修改、刪除成員的唯一辦法就是修改類型的定義代碼。

      但有時候,當需要為類型添加新功能但并不擁有類型的已有代碼時,比如,我們想要為.NET庫類型List添加自定義的dump方法時,該怎么做呢,答案是擴展方法。擴展方法允許在不修改類型定義的情況下,讓該類型獲得功能上的擴展。

      定義擴展方法

      當定義一個擴展方法時,第一個限制就是必須把方法定義在靜態類中,因此每一個擴展方法也必須聲明為靜態的。第二個限制是擴展方法要用this關鍵字對第一個參數進行修飾,這個參數也就是我們希望進行擴展的類型。

      比如下面的擴展方法允許.NET基類庫中的所有對象都擁有全新的方法DisplayDefiningAssembly()。

              static class MyExtensions
      {
      // 本方法允許任何對象顯示它所處的程序集
      public static void DisplayDefiningAssemlby(this object obj)
      {
      Console.WriteLine("{0} is defined in: \n\t {1}\n",
      obj.GetType().Name,
      System.Reflection.Assembly.GetAssembly(obj.GetType()));
      }
      }

      調用擴展方法

      我們有兩種方式來使用擴展方法,第一種是在實例層次上調用擴展方法,第二種是靜態調用擴展方法。

              public void UsingExtensionMethods()
      {
      int myInt = 12345;

      // 1. 在實例層次上調用擴展方法
      myInt.DisplayDefiningAssemlby();

      // 2. 靜態調用擴展方法
      MyExtensions.DisplayDefiningAssemlby(myInt);
      }

      實例上,通過一個對象調用它的擴展方法只是編譯器的煙幕彈效果而已,背后編譯器會轉換成靜態方法的調用。

      其他注意事項

      上面說到,擴展方法本質上是可以從擴展類型的實例上調用的靜態方法。所以它和普通的方法是不一樣的,擴展方法不能直接訪問擴展類型的成員,從另外一個角度講,擴展方法即不是直接修改,也不是繼承。

      另外一個要注意的地方是:雖然表面上擴展方法是全局的,但其實他們受制于所處的命名空間,要使用在其他命名空間中定義的擴展方法時,我們首先需要導入該命名空間。

       

      Lambda表達式

      Lambda表達式的引入是與委托類型的使用密切相關的,本質上,Lambda表達式只是用更簡單的方式來書寫匿名方法,從而徹底簡化.NET委托類型的使用。下面我們一步一步的來看看Lambda表達式的簡化之路:

      實例找出整數List<T>中的偶數,我們調用了List<T>類型的FindALl()方法,這個方法需要System.Predicate<T>泛型委托,它用于接受類型為T的輸入參數并返回一個布爾值。

      傳統的委托使用方式

      傳統的委托使用方式會為委托目標定義一個單獨的方法,如下:

              public static void TraditionalDelegateSyntax()
      {
      List<int> list = new List<int>();
      list.AddRange(new int[] { 1, 5, 10, 20 ,33 });

      //使用傳統委托語法調用FindAll
      Predicate<int> callback = new Predicate<int>(IsEvenNumber);
      List<int> evenNumbers = list.FindAll(callback);

      foreach (int num in evenNumbers)
      Console.Write("{0}\t", num);
      //Output: 10 20
      }

      // Predicate<>委托的目標
      static bool IsEvenNumber(int i)
      {
      return (i % 2) == 0;
      }

      匿名方法取代顯示的委托函數

      這種方式讓我們不再需要完整的方法定義,對于一些專門為了委托而定義的函數而言是一個很大的簡化,如下:

              public static void AnonymousMethodSyntax()
      {
      List<int> list = new List<int>();
      list.AddRange(new int[] { 1, 5, 10, 20, 33 });

      //使用匿名方法
      List<int> evenNumbers = list.FindAll(
      delegate(int i)
      {
      return (i % 2) == 0;
      });

      foreach (int num in evenNumbers)
      Console.Write("{0}\t", num);
      //Output: 10 20
      }

      Lambda表達式

      Lambda表達式讓我們進一步簡化FindAll()的調用,使用新的語法時,底層的委托語法消失得無影無蹤,如下所示:

              public static void LambdaExpressionSyntax()
      {
      List<int> list = new List<int>();
      list.AddRange(new int[] { 1, 5, 10, 20, 33 });

      //使用Lambda表達式
      List<int> evenNumbers = list.FindAll(i => (i % 2) == 0);

      foreach (int num in evenNumbers)
      Console.Write("{0}\t", num);
      //Output: 10 20
      }

      Lambda表達式可以應用于任何匿名方法可以應用的場合,而且比匿名方法更加簡潔更節省編碼時間。其實C#編譯器只是把Lambda表達式翻譯為相應的普通匿名方法而已。

      Lambda表達式的格式:先定義參數列表,”=>”標記(可讀為:goes to)緊隨其后,然后是表達式。即:ArgumentsToProcess => StatementsToProcessThem

      Lambda表達式的參數可以是顯示類型化的也可以是隱式類型化的。比如上例中的參數i就是隱式類型化的,我們也可以寫為如下:

                  // 顯示定義參數的類型
      List<int> evenNumbers = list.FindAll((int i) => (i % 2) == 0);

      Lambda表達式也可以是一個代碼塊,其中包含多條代碼語句,用花括號括起來即可:

                  // 使用語句塊編寫Lambda表達式
      List<int> evenNumbers = list.FindAll((int i) =>
      {
      Console.WriteLine("processing value: {0}", i);
      bool isEven = (i % 2) == 0;
      return isEven;
      });

       

      對象初始化器

      C# 3.0提供的 對象初始化器語法用來初始化新類或新結構變量的狀態。使用這種語法,我們可以以一種非常簡潔的方式來創建對象和為對象的屬性賦值。如下:

          public class Point
      {
      public Point() { }
      public Point(int x, int y)
      {
      X = x;
      Y = y;
      }

      public int X { get; set; }
      public int Y { get; set; }
      }

      static void ObjectInitSyntax()
      {
      // 手動初始化各屬性
      Point aPoint = new Point();
      aPoint.X = 10;
      aPoint.Y = 20;

      // 使用新的對象初始化語法進行初始化
      Point bPoint = new Point { X = 10, Y = 20 };
      }

      使用初始化語法調用構造函數

      上面的示例中,對象初始化語法會隱式調用默認的構造函數初始化Point實例,而且我們還可以顯示調用定制的構造函數,如下:

              static void ObjectInitSyntax()
      {
      // 在這里,默認構造函數被隱式調用
      Point bPoint = new Point { X = 10, Y = 20 };

      // 我們也可以顯示調用默認構造函數
      Point cPoint = new Point() { X = 10, Y = 20 };

      // 我們還可以調用自定義的構造函數,只是這里1, 2會被10, 20覆蓋
      Point dPoint = new Point(1, 2) { X = 10, Y = 20 };
      }

      初始化內部類型

      當我們用這種語法來初始化一個“復雜”的對象時,其優點會更具說服力,假如我們有類Rectangle如下,可以明顯的看出,對象初始化語法不但大大減少了我們敲打鍵盤的次數,也更加的簡潔明了。

          public class Rectangle
      {
      public Point TopLeft { get; set; }
      public Point BottomRight { get; set; }
      }

      static void CompareObjectInitMethods()
      {
      // 傳統初始化方法
      Rectangle r = new Rectangle();
      Point p1 = new Point();
      p1.X = 10;
      p1.Y = 10;
      r.TopLeft = p1;
      Point p2 = new Point();
      p2.X = 20;
      p2.Y = 20;
      r.BottomRight = p2;

      // 對象初始化語法
      Rectangle r2 = new Rectangle
      {
      TopLeft = new Point { X = 10, Y = 10 },
      BottomRight = new Point { X = 20, Y = 20 }
      };
      }

      集合的初始化

      集合初始化語法非常類似于對象初始化語法,它使得我們可以像初始化普通數組一樣初始化容器(如ArrayList或List<T>)。

              static void CollectionInitSyntax()
      {
      // 初始化標準數組
      int[] numbers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

      // 初始化一個ArrayList
      ArrayList list = new ArrayList { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

      // 初始化一個List<T>泛型容器
      List<int> list2 = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

      // 如果容器存放的是非簡單對象
      List<Point> pointList = new List<Point>
      {
      new Point { X = 2, Y = 2},
      new Point { X = 3, Y = 3}
      };

      // 使用恰當的縮進和嵌套的大括號會使代碼易于閱讀,同時節省我們的輸入時間
      // 想想如果不使用初始化語法構造如下的List,將需要多少行代碼
      List<Rectangle> rectList = new List<Rectangle>
      {
      new Rectangle { TopLeft = new Point { X = 1, Y = 1},
      BottomRight = new Point { X = 2, Y = 2}},
      new Rectangle { TopLeft = new Point { X = 3, Y = 3},
      BottomRight = new Point { X = 4, Y = 4}},
      new Rectangle { TopLeft = new Point { X = 5, Y = 5},
      BottomRight = new Point { X = 6, Y = 6}}
      };
      }

       

      posted @ 2011-10-26 13:06  Life a Poem  閱讀(13297)  評論(14)    收藏  舉報
      主站蜘蛛池模板: 国产免费无遮挡吃奶视频| 亚洲高清国产拍精品熟女| 欧美视频免费一区二区三区| 色婷婷五月综合久久| 男女动态无遮挡动态图| 亚洲综合一区国产精品| 国产伦一区二区三区视频| 97亚洲色欲色欲综合网| 丰满高跟丝袜老熟女久久| 亚洲精品97久久中文字幕无码| 中文字幕日韩国产精品| 亚洲日韩精品无码av海量| 国产69精品久久久久99尤物 | 亚洲粉嫩av一区二区黑人| 国产成人一卡2卡3卡四卡视频| 国产精品日日摸夜夜添夜夜添无码| 亚洲色成人一区二区三区人人澡人人妻人人爽人人蜜桃麻豆 | 中文字幕无码中文字幕有码a| 国产午夜精品久久精品电影| 人妻少妇精品中文字幕| 人妻少妇精品中文字幕| 无码人妻丝袜在线视频| 日韩国产成人精品视频| 自拍偷自拍亚洲精品熟妇人 | 中文字幕国产精品一二区| 国产嫩草精品网亚洲av| 少妇人妻综合久久中文字幕| 成人午夜福利免费专区无码| 久久天天躁狠狠躁夜夜躁2o2o| 日韩精品中文字幕亚洲| 国产精品区一区第一页| 亚洲综合一区二区精品导航| 日韩av第一页在线播放| 久青草国产综合视频在线| 婷婷开心深爱五月天播播| 国产视频有码字幕一区二区| 亚洲中文字幕一区二区| 国产真实乱对白精彩久久| 丝袜欧美视频首页在线| 亚洲精品三区四区成人少| 中文字幕V亚洲日本在线电影|