Windbey中为了增强对集合的访问能力, MS设计了List<T>这么一个泛型集合, 其中有不少的增强功能,比如Foreach,ConvertAll,FindAll等等,并且为了方便使用MS在System名空间下引入了一些特制的Delegate.主要包括以下几个:
20 public delegate void Action<T>(T obj); //Used by ForEach21 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
Sort
Code public class SimpleTestCompare : IComparer<SimpleTest> { #region IComparer<SimpleTest> Members public int Compare(SimpleTest x, SimpleTest y) { if (x == null || y == null) return 0; int result; if (x.MasterId != y.MasterId) result = y.MasterId - x.MasterId; else result = y.VersionId - x.VersionId; if (result == 0) return 0; if (result < 0) return -1; return 1; } #endregion } static void Main(string[] args) { SimpleTestFactory factory = new SimpleTestFactory(); List<SimpleTest> list = factory.CreateSimpleTestFactory(); factory.Display(list); list.Sort(new SimpleTestCompare()); Console.WriteLine("Display after Sort"); factory.Display(list); } public class SimpleTest { public int MasterId { get; set; } public int VersionId { get; set; } } public class SimpleTestFactory { Random masteridRandom = new Random(); Random versionid = new Random(); private const int MAX_VALUE = 100; private const int MIN_VALUE = 10; public List<SimpleTest> CreateSimpleTestFactory() { List<SimpleTest> list = new List<SimpleTest>(); for (int index = 0; index < 10; ++index) { int masterid = masteridRandom.Next(MIN_VALUE, MAX_VALUE); for (int j = 0; j < 2; j++) { SimpleTest test = new SimpleTest(); test.MasterId = masterid; test.VersionId = masteridRandom.Next(MIN_VALUE, MAX_VALUE); list.Add(test); } Display(index); } return list; } public void Display(int i) { Console.WriteLine(i.ToString()); } public void Display(List<SimpleTest> list) { string str = "MasterId : {0,3} and versionId : {1,3};"; foreach (SimpleTest test in list) Console.WriteLine(string.Format(str, test.MasterId, test.VersionId)); } }
执行结果为:
Convert
List<float> fs = new List<float>();
fs.Add(5.2);
fs.Add(3.6)
...
fs.Add(8.8)
List<int> is = fs.ConvertAll<int>(delegate(float f){return (int)f;});
利用这些特制的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表达式目前不支持多条语句.
转载于:https://www.cnblogs.com/joechen/archive/2008/08/20/1272354.html
相关资源:DirectX修复工具V4.0增强版