C#委托使用详解
委托概念
委托是一种数据类型,类型安全的指向函数的指针。
委托的定义与使用
使用步骤:
1.定义方法
2.声明委托类型(参数列表、返回值要和要指向的方法一致)
3.定义委托变量并指向(匿名)方法
4.调用委托
举个例子:
class Program { delegate string StrProcess(string s); static void Main(string[] args) { StrProcess sp = new StrProcess(ToLower);//标准写法 Console.WriteLine(sp("WEED")); sp = Invert;//简写 Console.WriteLine(sp("WEED")); Console.ReadLine(); } static string ToLower(string s) { Console.WriteLine("我是方法:ToLower,我的功能是将字符串转为小写"); return s.ToLower(); } static string Invert(string s) { Console.WriteLine("我是方法:Invert,我的功能是将字符串反转"); var arr= s.ToCharArray(); int length = arr.Length; string c = ""; for (int i = 0; i < length; i++) { c+= arr[length - i - 1]; } return c; } }
运行结果如下:
委托传参
我们可以把委托对象(指向委托的方法)当做方法的参数进行传递。
举个例子:
class Program { delegate string StrProcess(string s); static void Main(string[] args) { CW("SDdgsdgS", new StrProcess(ToLower));//标准写法 CW("SDdgsdgS", Invert);//简写 Console.ReadLine(); } static string ToLower(string s) { Console.WriteLine("我是方法:ToLower,我的功能是将字符串转为小写"); return s.ToLower(); } static string Invert(string s) { Console.WriteLine("我是方法:Invert,我的功能是将字符串反转"); var arr= s.ToCharArray(); int length = arr.Length; string c = ""; for (int i = 0; i < length; i++) { c+= arr[length - i - 1]; } return c; } static void CW(string s,StrProcess sp) { Console.WriteLine("我是方法:CW,我的功能是根据传来的委托打印字符串"); Console.WriteLine(sp(s)); } }
运行结果如下:
通过打印结果我们可以看出:在执行CW方法时,会先执行指向委托的方法,这样可以实现方法的重用。效果等同于如下代码,但是如下代码复用性要差的多:
class Program { static void Main(string[] args) { CWToLower("SDGDDS"); CWInvert("DDSsggd"); Console.ReadLine(); } static string ToLower(string s) { Console.WriteLine("我是方法:ToLower,我的功能是将字符串转为小写"); return s.ToLower(); } static string Invert(string s) { Console.WriteLine("我是方法:Invert,我的功能是将字符串反转"); var arr= s.ToCharArray(); int length = arr.Length; string c = ""; for (int i = 0; i < length; i++) { c+= arr[length - i - 1]; } return c; } static void CWToLower(string s) { Console.WriteLine("我是方法:CWToLower,我的功能是先将字符串转为小写然后打印字符串"); string r= ToLower(s); Console.WriteLine(r); } static void CWInvert(string s) { Console.WriteLine("我是方法:CWInvert,我的功能是先反转字符串然后打印字符串"); string r= Invert(s); Console.WriteLine(r); } }
多播委托
我们可以让多个方法指向同一个委托,从而形成委托链。
举个例子:
StrProcess sp = ToLower; sp += Invert; Console.WriteLine(sp("WEED")); sp -= ToLower; Console.WriteLine(sp("ksgwsz")); Console.ReadLine();
运行结果如下:
通过结果我们可以看到委托指向的两个方法都被执行了,但是这却有一个弊端,只有最后一个方法的返回值才能被返回。这个问题我们可以通过定义内部集合的方式解决。
匿名方法
有时候我们不想定义一个具体的和委托类型对应方法,这个时候我们可以使用匿名方法,让匿名方法指向委托。
匿名方法编译后会生成一个方法和一个指向该方法的静态的委托对象。匿名方法一定是结合委托使用。一次性使用的方法。匿名方法可以省略参数。
举个例子:
运行结果如下:
系统内置委托
其实.net Framework类库中定义了大量的委托类型,特别是泛型委托。我们完全可以利用这些委托而不需要自己额外的定义委托。
(1)Action<in T1,….,int T16>,最多可以传入16个参数,无返回值,可以用来遍历集合。 public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
(2)Predicate<T> 返回bool,可以用来当条件。public delegate bool Predicate<in T>(T obj);
(3)Comparison<T> 返回int。public delegate int Comparison<in T>(T x, T y); //list.Sort
(4)Func<in T1,…,in T16,out TResult>,自定义参数类型,最多16个输入参数,只有一个返回值。public delegate TResult Func<in T, out TResult>(T arg);
Action使用举例如下:
Predicate、Comparison使用举例如下:
Func使用举例如下: