最近在看深入理解C#,发现这是一本很不错的书,将很多C#的知识点联系了起来,更像是一本C#历史书,从C# 1一步步介绍到C# 4。
所以准备一边看,一边整理读书笔记。那么就先从委托开始。
委托是C#中一个非常重要的概念,从C# 1开始就有了委托这个核心概念,在C# 2和C# 3中委托又有了很多改进。
通过委托,我们可以将一个方法当作对象封装起来,并且在运行时,我们可以通过这个对象来完成方法的调用。
委托的使用首先,来个简单的例子,苹果只负责设计iphone,而把组装iphone的工作委托给富士康做。
class Apple { //声明委托类型 public delegate void AssembleIphoneHandler(); public AssembleIphoneHandler AssembleIphone; public void DesignIphone() { Console.WriteLine("Design Iphone By Apple"); } } class Foxconn { //与委托类型签名相同的方法 public void AssembleIphone() { Console.WriteLine("Assemble 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.DesignIphone(); //委托实例的调用 apple.AssembleIphone(); //通过Invoke进行显示调用 //apple.AssembleIphone.Invoke(); Console.Read(); } }
从上面的例子中,可以体会一下委托的使用。使用委托需要满足4个条件:
声明一个委托类型
找到一个跟委托类型具有相同签名的方法(可以是实例方法,也可以是静态方法)
通过相同签名的方法来创建一个委托实例
通过委托实例的调用完成对方法的调用
委托类型和委托实例当我们使用委托的时候,一定要注意这两个概念。
委托类型,是通过delegate关键字声明的一种类型,例如上面例子中的:
public delegate void AssembleIphoneHandler();
注意,"AssembleIphoneHandler"是一个委托类型,它有自己的方法,可以创建相关的实例。通过"ILSpy"可以看到"AssembleIphoneHandler"的方法以及父类信息。
委托类型的声明过程中描述了该委托类型的签名(返回类型,参数列表),这个签名就决定了那个方法可以用来创建一个改委托类型的委托实例;同时,这个签名还表示了该委托实例调用的签名。
而委托实例,就是通过委托类型进行实例化的对象,例如上面例子中的:
apple.AssembleIphone = new Apple.AssembleIphoneHandler(foxconn.AssembleIphone);
在创建委托实例的过程中,我们需要找到一个跟委托类型签名相同的方法来完成委托实例的创建。
委托的合并和删除在前面的例子中,委托实例(apple.AssembleIphone)只对应一个操作(方法foxconn.AssembleIphone)。但是,每个委托实例都有一个操作列表,称为委托实例的调用列表(invocation list)。在System.Delegate类中,有两个静态方法Combine和Remove,通过这两个静态方法,我们就可以进行两个委托实例的调用列表的合并和删除。
接着上面的例子进行修改,这次来看看委托的合并和删除。
class Foxconn { //与委托类型签名相同的方法 public void AssembleIphone() { Console.WriteLine("Assemble Iphone By Foxconn"); } public void PackIphone() { Console.WriteLine("Pack Ipnone By Foxconn"); } 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(); //委托实例的调用 apple.AssembleIphone(); //通过Invoke进行显示调用 //apple.AssembleIphone.Invoke(); Console.Read(); } }