C#中常见的系统内置委托用法,主要包括了Action类的委托、Func类的委托、Predicate<T>委托、Comparison<T>委托等,需要的朋友可以参考下
一、Action类的委托
1.Action委托 封装一个方法,该方法不具有参数并且不返回值
2.Action<T>委托 封装一个方法,该方法只有一个参数并且不返回值
3.Action<T1,T2>委托 封装一个方法,该方法具有两个参数并且不返回值
…… ……
Action a1 = () => Console.WriteLine("hello");
Action<int, int> a2 = (x, y) => Console.WriteLine(x+y);
a2(10,20);
总结:
Action类的委托最少可以传入0个参数,最多可以传入16个参数,参数类型皆为逆变,并且不返回值。
二、Func类的委托
1.Func(TResult)委托封装封装一个不具有参数但却返回 TResult 参数指定的类型值的方法
2.Func(T,TResult)委托 封装一个具有一个参数并返回 TResult 参数指定的类型值的方法
3.Func(T1,T2,TResult)委托 封装一个具有两个参数并返回 TResult 参数指定的类型值的方法
…… ……
Func<int, int, int> fun = (x, y) => x + y;
int sum = fun(20,30);
总结:
Func类的委托最少可以传入输入泛型参数(in,逆变) 1个,最多可以传入输入泛型参数(in,逆变) 16个,传入的输出泛型参数(out,协变)有且只有一个,这个类型是此委托封装的方法的返回值类型。
三、Predicate<T>委托(返回bool)
表示定义一组条件并确定指定对象是否符合这些条件的方法
predicate 是返回bool型的泛型委托
predicate<int> 表示传入参数为int 返回bool的委托
Predicate有且只有一个参数,返回值固定为bool
第一种写法:
List<int> newList = list.FindAll(new Predicate<int>(d => d > 3));
第二种写法:
Predicate<int> concat2 = (c => c > 3);
var newlist2 = list.FindAll(concat2);
#region Predicate<T>委托示例
//需求:查找整型集合list中大于3的所有元素组成的新集合,并打印出集合元素
List<int> list = new List<int>() { 1, 2, 3, 4, 5 };
//将匿名方法分配给 Predicate<T> 委托实例
Predicate<int> concat1 = delegate(int i) { return i > 3; };
var newlist1 = list.FindAll(concat1);
//将 lambda 表达式分配给 Predicate<T> 委托实例
Predicate<int> concat2 = (c => c > 3);
var newlist2 = list.FindAll(concat2);
newlist1.ForEach(i => Console.WriteLine(i));
newlist2.ForEach(i => Console.WriteLine(i));
Console.ReadKey();
#endregion
总结:
Predicate<T>委托封装一个方法,该方法传入一个类型参数,这个参数是指要比较的对象的类型,此类型参数是逆变,同时接收一个参数(该参数就是要按照由此委托表示的方法中定义的条件进行比较的对象,参数的类型就是传入的类型参数的类型),该方法始终返回bool类型的值。如果该对象符合由此委托表示的方法中定义的条件,则为 true;否则为 false。
四、Comparison<T>委托(返回int)
表示比较同一类型的两个对象的方法
#region Comparison<T>委托示例
//需求:将整型集合list中的所有元素倒序排列打印出来
List<int> list = new List<int>() { 1, 2, 3, 4, 5 };
//将匿名方法分配给 Comparison<T> 委托实例
Comparison<int> concat1 = delegate(int i, int j) { return j - i; };
//将 lambda 表达式分配给 Comparison<T> 委托实例
Comparison<int> concat2 = (i, j) => j - i;
list.Sort(concat1);
list.ForEach(c => Console.WriteLine(c.ToString()));
list.Sort(concat2);
list.ForEach(c => Console.WriteLine(c.ToString()));
Console.ReadKey();
#endregion
总结:
Comparison<T>委托封装一个方法,该方法传入一个类型参数,这个参数是指要比较的对象的类型,此类型参数是逆变,同时接收两个同类型的参数(这两个参数就是要比较的两个对象,参数的类型就是传入的类型参数的类型),始终返回int类型的值,即一个有符号整数,指示 x 与 y 的相对值,如下表所示。
值 含义
小于0 x 小于y
0 x 等于y
大于0 x 大于y
例子一,求数组最大值
public delegate int DelCompare<T>(T o1,T o2); class Program { static void Main(string[] args) { int[] nums = { 2,5,6,9,1,5,8}; int max = GetMax<int>(nums, delegate(int max1,int num) { return max1 - num; }); int max3 = GetMax<int>(nums,Compare); Console.WriteLine(max); Console.ReadKey(); } public static int Compare(int o1,int o2) { return o1 - o2; } public static T GetMax<T>(T[] nums, DelCompare<T> del) { T max = nums[0]; for (int i = 0; i < nums.Length; i++) { if (del(max, nums[i]) < 0) { max = nums[i]; } } return max; } }
例子二,用系统自带Func求数组最大值
int[] nums = { 9, 8, 6, 7, 5, 10, 22, 32, 14, 33, 21 }; Func<int> max = () => { int m = nums[0]; for (int i = 0; i < nums.Length; i++) { if (nums[i] > m) { m = nums[i]; } } return m; }; Console.WriteLine(max());
例子三:使用Action自带的委托
Action a1 = () => { Console.WriteLine("你好"); }; a1(); Action<string> a2 = m => { Console.WriteLine(m); }; a2("好啊"); Action<int, int> a3 = (x, y) => { Console.WriteLine(x+y); }; a3(5,10); Func<int, int, int, int> fun = (a, b, c) => { return a + b + c; }; int result = fun(1,2,3); Console.WriteLine(result);
例子四,使用lambda表达式求List集合大于6的值
List<int> list = new List<int>() { 1,2,3,4,55,32,89,21,4,11,22,36}; IEnumerable<int> ie = list.Where(x => { return x > 6; }); foreach (var item in ie) { Console.WriteLine(item); }