C# lambda運算式

來源:互聯網
上載者:User

標籤:

今天高手討論了一個問題:
FuncList.FindAll(pNodes => pNodes.ParentID == "01")
等價於 if(pNodes.ParentID == "01") return pNodes; 
實際就是一個委託函數的縮寫。
總結一下:

“Lambda 運算式”是一個匿名函數,它可以包含運算式和語句,並且可用於建立委託或運算式分類樹類型。 所有 Lambda 運算式都使用 Lambda 運算子 =>,該運算子讀為“goes to”。該 Lambda 運算子的左邊是輸入參數(如果有),右邊包含運算式或語句塊。Lambda 運算式 x => x * x 讀作“x goes to x times x”。
http://baike.baidu.com/view/3048187.htm

Windbey中為了增強對集合的訪問能力, MS設計了List<T>這麼一個泛型集合, 其中有不少的增強功能,比如Foreach,ConvertAll,FindAll等等,並且為了方便使用MS在System名空間下引入了一些特製的Delegate.主要包括以下幾個:

   20     public delegate void Action<T>(T obj);   //Used by ForEach

   21     public delegate int Comparison<T>(T x, T y);  //Used by Sort

   22     public delegate TOutput Converter<TInput, TOutput>(TInput input);    //Used by ConvertAll

   23     public delegate bool Predicate<T>(T obj); //Used by FindAll


利用這些特製的Delegate,再加上匿名方法的使用,我們可以獲得更加簡潔,有效代碼. 具體的例子我以前有過介紹.現在在Orcas中, MS加入了lambda運算式的概念. lambda運算式是匿名方法的進一步增強. 利用它可以更加方便的寫出新的方法. 而且語義上更加接近人性化.

同樣它也引入了一些特製的Delegate:

   20       public delegate T Func<T>();

   21       public delegate T Func<A0, T>(A0 arg0);

   22       public delegate T Func<A0, A1, T>(A0 arg0, A1 arg1);

   23       public delegate T Func<A0, A1, A2, T>(A0 arg0, A1 arg1, A2 arg2);

   24       public delegate T Func<A0, A1, A2, A3, T>(A0 arg0, A1 arg1, A2 arg2, A3 arg3);


和2.0中特製的Delegate對比, 你會發現它們有很多相同之處:

   20       public delegate int Comparison<T>(T x, T y);   
   21       public delegate int Func<T,T,int>(T arg0, T arg1);

   22       public delegate TOutput Converter<TInput, TOutput>(TInput input); 
   23       public delegate TOutput Func<TInput, TOutput>(TInput arg0);

   24       public delegate bool Predicate<T>(T obj);

   25       public delegate bool Func<T,bool>(T arg0);


也就是說3.0中特製的Delegate比2.0的更一般化, 2.0是3.0的特例. 所以我們完全可以將lambda運算式運用於List<T>的一些增強方法中.

Sort方法

   20  List<int> list=new List<int>();

   21  var numbers = new []{ 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

   22  list.AddRange(numbers);

   23  list.Sort(delegate (int a, int b)

   24                {

   25                 return a.CompareTo(b);

   26                }

   27            );

   28  //use lambda

   29  list.Sort((a,b)=>a.CompareTo(b));


ConvertAll方法

   20  List<int> doubleList =list.ConvertAll<int>(delegate (int i)

   21                                             {

   22                                                 return i*2;

   23                                             });

   24  //use lambda

   25  var doubleList2=list.ConvertAll<int>(i=>i*2);


FindAll方法

   20  List<int> lowerThanFiveList =list.FindAll(delegate (int i)

   21                                             {

   22                                                 return i<5;

   23                                             }

   24                                           );

   25  var lowerThanFiveList2=list.FindAll(i=>i<5);


從上面的例子可以看出利用lambda運算式寫出的代碼更加簡潔易懂.  (以後代碼都經過編譯測試,可不是我杜撰的.)

以上是將lambda運算式運用於2.0當中. 但是在熟悉了3.0後, 你會發現2.0中的List<T>提供的增強方法完全是多餘的了. 其實這些增強方法往往並不限於List<T>, 通常對於IEnumerable<T>對象都是適用的. 但是如果去改動IEnumable<T>介面那麼影響實在太大了,將涉及很多的類. 所以MS僅僅在List<T>中提供了這些增強方法. 不過通過List<T>的一個建構函式,你可以使得所有的IEnumerable<T>對象可以方便的轉化為List<T>,然後再利用這些方法.

這可以說是一個很取巧的方法, 不過在有了3.0的Extension Method的支援下, 就不用這麼麻煩了, 而且MS還內建了一系列更強的集合操作方法.

比如之前的FindAll方法,我們現在可以這樣寫:

   21      var numbers = new []{ 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

   22      var lowerThanFive=numbers.Where(i=>i<5); //never need List<T>, just operate on T[] or any other types implement IEnumerable<T>

   23      foreach (var v in lowerThanFive)

   24          Console.WriteLine(v);   


ConvertAll方法

   21      var doubleList3=numbers.Select(i=>i*2);

   22      foreach (var v in doubleList3)

   23          Console.WriteLine(v); 


Sort方法

   21      var orderList =numbers.OrderBy(i=>i);

   22      foreach (var v in orderList)

   23          Console.WriteLine(v); 

甚至還有很多更強大的功能:
比如我要取numbers數組中最大的5個數.

   21      var big5 =numbers.OrderByDescending(i=>i).Take(5);

   22      foreach (var v in big5)

   23          Console.WriteLine(v);


通過Orcas的Extension Method和Lambda運算式, MS為集合的操作提供了更加方便強大的功能. 這裡尚未用到Standard Query Operators, 不然代碼還要被簡化. 

當然Linq現在僅僅是一個Tech Preview 版本. 尚有很多不足.尤其在智能感知(IntelliSense)方面:
1.  var numbers = new []{ 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 採用這種寫法時, numbers沒有智能感知功能.
2. 使用lambda運算式時,如果不聲明T類型,對於其中的變數沒有智能感知功能.這點很是奇怪, Linq竟然沒有強制宣告類型.

   21     var lowerThanFive=numbers.Where<int>(i=>i<5);

   22     var lowerThanFive=numbers.Where(i=>i<5);

以上兩種寫法竟然都沒問題, 顯然在下一種寫法中變數i 無法獲得智能感知的能力. 
3. numbers.OrderBy(...),在寫這個方法時,numbers的智能感知中並沒有OrderBy這個方法, 但是編譯運行沒有問題.
4. lambda運算式目前不支援多條語句.

C# lambda運算式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.