C#委托的基本概念(2)

这次,我们在Foxconn类中加了打包和运输的方法,这样,可以通过Combine方法将组装、打包和运输三个操作合并到委托实例apple.AssembleIphone的调用列表中。

当我们调用委托实例的时候,委托实例的调用列表中的所有操作会依次被执行。

注意,一般在代码中,很少直接使用Combine和Remove方法的显式调用,而是通过"+="和"-="操作符来实现。

委托是不易变的

这里有一点要提的是,委托是不易变的,一旦创建了一个委托实例后,这个实例的所有内容都不能被改变了(就像string一样,string也是不易变的)。

所以说Combine和Remove都没有改变委托实例,都是新建了一个委托实例。

委托调用列表

在使用调用列表的时候,有些关键点需要注意一下,假如说一个委托实例的调用列表为[methodA, methodB, methodC]。那么当我们调用委托实例的时候,methodA, methodB, methodC会依次被执行。

如果上面A-C三个方法都有返回值,我们只能得到最后一个操作的返回值,其他的返回值都将被忽略。

如果调用列表中的一个操作有异常,那么所有的下游操作都不会被执行。

举例,我们在PackIphone方法中加入一个异常,那么委托列表中的ShipIphone操作将不会被执行到:

class Foxconn { //与委托类型签名相同的方法 public void AssembleIphone() { Console.WriteLine("Assemble Iphone By Foxconn"); } public void PackIphone() { throw new NotImplementedException(); } public void ShipIphone() { Console.WriteLine("Ship Iphone By Foxconn"); } } class Program { static void Main(string[] args) { Apple apple = new Apple(); Foxconn foxconn = new Foxconn(); //创建委托实例 apple.AssembleIphone = new Apple.AssembleIphoneHandler(foxconn.AssembleIphone); //apple.AssembleIphone += new Apple.AssembleIphoneHandler(foxconn.PackIphone); apple.AssembleIphone = (Apple.AssembleIphoneHandler)Delegate.Combine(apple.AssembleIphone, new Apple.AssembleIphoneHandler(foxconn.PackIphone)); apple.AssembleIphone += new Apple.AssembleIphoneHandler(foxconn.ShipIphone); apple.DesignIphone(); //委托实例的调用 try { apple.AssembleIphone(); } catch { Console.WriteLine("an exception happened"); } Console.Read(); } }

GetInvocationList

对于上面两个问题,我们可以通过委托实例的GetInvocationList()方法,通过这个方法可以得到调用列表中的所有操作。

这样,就可以显示调用委托来进行异常处理或者返回值的保存。

foreach (Apple.AssembleIphoneHandler method in apple.AssembleIphone.GetInvocationList()) { try { method(); } catch { Console.WriteLine("an exception happened"); } } 

总结

本文介绍了委托的基本概念,以及委托类型和委托实例的区别。

委托本质上是一个派生自System.MulticastDelegate的类,我们可以通过特定的(与委托类型签名相同)的方法创建委托实例,通过委托是,可以间接完成某些操作。

同时,可以通过Combine和Remove操作来进行委托实例的调用列表的合并和删除。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/f780f8507a6904e9cdec01a64dbd929e.html