Windbey中為了增強對集合的訪問能力, MS設計了List<T>這么一個泛型集合, 其中有不少的增強功能,比如Foreach,ConvertAll,FindAll等等,並且為了方便使用MS在System名空間下引入了一些特制的Delegate.主要包括以下幾個:
public delegate void Action<T>(T obj); //Used by ForEach public delegate int Comparison<T>(T x, T y); //Used by Sort public delegate TOutput Converter<TInput, TOutput>(TInput input); //Used by ConvertAll 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對比, 你會發現它們有很多相同之處:
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> 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));
FindAll方法
20 List<int> lowerThanFiveList =list.FindAll(delegate (int i) { return i<5; } ); 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表達式目前不支持多條語句.