提及委托和事件,我就想起了再学校的时候,当时死记硬背去记什么是委托什么是事件。记得当时蝼某人问我,委托是什么?可是只知道一点点,就跟他说:打个比方,我要喝水,可是我不去买,我委托你去帮我买水。这就是委托,够直白简单了吧。html
语法: public delegate void BuyWaterEventHandler();c#
其中 delegate 是关键字,声明委托的时候命名时后缀加入EventHandle数组
这就是一个简单的委托,就是这么简单。咱们相对于平时使用的方法有什么区别吧函数
方法:学习
public static string BuyWaterSlef() { return "本身去买水"; }
咱们看方法,是实现买水这个功能的,而委托是委托你去帮我买水的。方法是具体作事实现功能,委托只是命令而已。spa
咱们具体使用委托来实现刚刚那个委托蝼某人去买水的程序设计。设计
/// <summary> /// 蝼某人去买水的类 /// </summary> public class LouBuy { /// <summary> /// 蝼某人买水的方法 /// </summary> /// <returns></returns> public static string LouBuyWater() { return "蝼某人去买水"; } } /// <summary> /// 定义买水的委托 /// </summary> /// <returns></returns> public delegate string BuyWater(); /// <summary> /// 买水委托实现的类 /// </summary> public class MainBuy { /// <summary> /// 实现委托 /// </summary> /// <returns></returns> public static string BuyFun() { /// 委托中加入蝼某人的方法 BuyWater buyWater = new BuyWater(LouBuy.LouBuyWater); ///返回结果 return buyWater(); } }
最后这里输出的是”蝼某人去买水”code
BuyWater buyWater = new BuyWater(LouBuy.LouBuyWater);htm
这里声明委托方法,BuyWater委托中加入LouBuy.LouBuyWater买水的方法,这个方法参数必须加入,由于委托的构造函数参数不为空。同时须要注意委托参数的返回类型都是要和具体委托方法同样的。对象
在这个例子中都是返回的string,都是无参数的
上面咱们简单的介绍了下委托及其用法,这里咱们能够了解一下委托链,顾名思义,委托链也就是委托连续,啥意思呢?继续上面的例子,我委托蝼某人去买水,而后顺带买包辣条。
/// <summary> /// 蝼某人去买水的类 /// </summary> public class LouBuy { /// <summary> /// 蝼某人买水的方法 /// </summary> /// <returns></returns> public static void LouBuyWater() { Console.WriteLine ("蝼某人去买水";) } /// <summary> /// 楼某人买辣条方法 /// </summary> /// <returns></returns> public static void LouBuyLT() { Console.WriteLine ("楼某人又买了辣条";) } } /// <summary> /// 定义买水的委托 /// </summary> /// <returns></returns> public delegate void BuyWater(); /// <summary> /// 买水委托实现的类 /// </summary> public class MainBuy { /// <summary> /// 实现委托 /// </summary> /// <returns></returns> public static void BuyFun() { /// 委托中加入蝼某人的方法 BuyWater buyWater = new BuyWater(LouBuy.LouBuyWater); buyWater += LouBuy.LouBuyLT; ///返回结果 Console.WriteLine (buyWater();) } }
这里就至关于我委托蝼某人作了两件事情,先去买水而后顺带买了辣条,委托链(多播委托)可使用+=来增长委托中调用的方法,同理也可以使用-=来删除委托中调用的方法.
注意,委托链(多播委托)--委托的签名必须返回void,不然就只能获得委托调用的最后一个方法的结果。同时委托链(多播委托)中注意不要调用一些必须有特定顺序的方法,由于委托中调用其方法链的顺序并未正式定义。
委托链(多播委托)还可能出现一个很是严重的问题,也就是在委托中多个方法调用时,一旦出现了异常报错,则整个迭代都会中止。
class Pragram { static void One() { Console.WriteLine("one"); throw new Exception("抛出异常报错"); } static void Two() { Console.WriteLine("two"); } public delegate void ActionMain(); static void Main() { ActionMain actionMain = One; actionMain += Two; try { actionMain(); } catch (Exception) { Console.WriteLine("异常报错"); } } }
在这个委托调用中,遇到抛出异常错误时就会中止迭代。最终返回结果为
one
抛出异常报错
上面讲到多播委托中一个调用抛出异常,整个迭代都会中止。下面讲解一个解决此问题的方法。在Delegate类中定义了GetInvocationList()方法,它返回的是Delegate对象数组,如今可使用这个委托调用与委托直接相关的方法,捕获异常,并继续下一次迭代。
class Pragram { static void One() { Console.WriteLine("one"); throw new Exception("抛出异常报错"); } static void Two() { Console.WriteLine("two"); } public delegate void ActionMain(); static void Main() { ActionMain actionMain = One; actionMain += Two; Delegate[] delegates = actionMain.GetInvocationList(); foreach (ActionMain item in delegates) { try { item(); } catch (Exception) { Console.WriteLine("抛出异常"); } } } }
再看咱们对出现问题的代码进行修改,这里抛出异常以后会继续迭代,并不会中止,返回的结果是
one
抛出异常错误
Two
咱们上面介绍到委托
public delegate void BuyWater(string a); BuyWater buyWater = new BuyWater(LouBuy.LouBuyWater);
下面咱们介绍另外两种委托形式,Action<T>委托和Fun<T>委托
Action<T>委托表示引用一个void返回类型的方法,能够没有参数,也能够有不少参数,一个参数Action<in T>,l两个参数Action<in T1,in T2>
Action<string> action=LouBuy.LouBuyWater;
Fun<T>委托表示能够调用容许带返回类型的参数,Fun<out TResult>表示委托类型能够调用带返回类型且无参数的方法,Fun<in T,out TResult>调用带返回类型带参数的方法
Func<string, string> buyWater = LouBuy.LouBuyWater;//表示返回string类型,参数也是string类型的一个方法
之前总在说委托与事件,都没有一次去了解熟悉它,如今得好好巩固一下了。到这里就介绍完了委托,看上去也挺简单的。咱们下一节继续看Event事件。而后结合委托一块儿看看委托加事件如何运用的。
再长的路,一步步也能走完,再短的路,不迈开双脚也没法到达。
欢迎你们扫描下方二维码,和我一块儿学习更多的C#知识