在C#我们可以自定义委托,但是C#为什么还要内置泛型委托呢?因为我们常常要使用委托,如果系统内置了一些你可能会用到的委托,那么就省去了定义委托,然后实例化委托的步骤,这样一来既使代码看起来简洁而干净又能提高程序员的开发速度,何乐不为呢!通过本文可以让你复习扩展方法,同时可以循序渐进的了解系统内置泛型委托的实现以及委托逐步的演化过程。
Action概念:封装一个方法,该方法具有五个参数并且不返回值。并且类型参数为逆变
下面我就自定义实现一个Action<T>无返回值的委托。我们同样定义一个Person类,似乎我随笔中永远都离不开Person的话题,哈哈!请看如下代码
public class Person { public string Name { get; set; } public int Age { get; set; } public bool Gender { get; set; } }
然后在控制台中通过 ForEach 方法模拟Action委托,先定义一个获得Person的列表GetList()
static List<Person> GetList() { List<Person> list = new List<Person>() { new Person(){ Name = "花千骨 (女娲后人及妖神)", Age = 12, Gender = false}, new Person(){ Name = "白子画 (长留尊上)", Age = 13, Gender = true}, new Person(){ Name = "东方彧卿 (异朽阁主及蜀国大学士)", Age = 14, Gender = true}, new Person(){ Name = "轻水 (长留弟子)", Age = 15, Gender = false}, new Person(){ Name = "孟玄朗 (蜀国皇帝及长留弟子)", Age = 16, Gender = true} }; return list; }
因为我们知道在用委托时,有这样几个步骤:
(1)定义委托
(2)实例化委托
(3)将方法指针添加到实例化委托对象中
但是现在我们无需定义委托,已经有了内置委托,只需将其实例化即可,同时添加方法的指针一般是有明确的方法,如果我们只是临时的用方法,这时就可以派匿名方法上场了,所以上面三步就可以简化成两步。代码如下:
var list = GetList(); list.ForEach(new Action<Person> ( delegate(Person p) { Console.WriteLine(p.Name); } ));
上述代码颇有点JQuery中Each的遍历方法的意味。结果打印出:
我们知道ForEach这个方法里面的的参数就是 Action<T> action ,所以我们可以直接进行如下简写
list.ForEach(delegate(Person p) { Console.WriteLine(p.Name); });
其打印结果和上面是一样的。其代码可以继续进行更加的精简,不着急,我们循序渐进的来。
Predicate概念:定义一组条件并确定指定对象是否符合这些条件的方法。返回值为bool类型,并且类型参数为逆变。
用到此泛型委托莫过于List中的 FindAll() 方法了,它就是从一个集合中根据条件筛选出一个新的集合出来。上节刚好学过扩展方法,我们可以自定义实现这个方法用扩展方法加在泛型集合List上根据 Predicate 委托的参数条件进行筛选。
static List<T> SelfDefineFindAll<T> (this List<T> list, Predicate<T> pre) /*注意:既然是添加的扩展方法,在此例中控制台的Program也要声明为静态类*/ { List<T> preList = new List<T>; /*根据条件筛选出的数据添加到该集合中*/ foreach (T t in list) { if (pre(t)) /*根据条件进行筛选*/ { preList.Add(t); } } return preList; }
我们查询出年纪大于13岁的并且根据ForEach来遍历筛选出来的数据,代码如下:
var list = GetList(); var preList = list.SelfDefineFindAll(delegate(Person p) { return p.Age > 13; }); preList.ForEach(delegate(Person p) { Console.WriteLine(p.Name); });
结果打印出正确的结果,如下:
而通过C#中的FindAll,则只需如下做即可同样达到上述的效果,只是不是扩展方法罢了:
list.FindAll(delegate(Person p) { return p.Name});
上述代码其实可以更加精简,不着急,我们一步一步循序渐进的来。
Comparison概念:表示比较同一类型的两个对象的方法。参数类型为逆变,返回值为int。