在C++中有各种各样的指针,其中,有一种指针是指向函数或者说是指向方法的,我们可以通过调用这个指针来调用其指向的方法。但是,这样的指针是不安全的。如果我们简单的把C++的指针认为是一个记录内存地址的空间,那么,方法指针里记录的就是目标方法的调用地址。但是,C++并没有对指针指向的对象加以任何的限制,你不知道这个方法会返回什么,不知道这个方法要接收多少个参数,也不知道接收的参数又是什么类型,并且在C++中,指针还可以参与运算。因此,对于调用者而言,除了看到一个地址,其余一概不知道,一切要等到调用以后才真向大白。这样的指针常常被一些不轨之人所利用,让方法指针指向一个破坏系统的方法,就好比给你一把钥匙,让你打开一个盒子,盒子里面是什么?也许是蛋糕,也许那就是潘多拉之盒。
由于方法指针不完善,C#针对这一现象进行了改进——委托。委托的作用与方法指针一样,用它来指向一个方法,并且提供给客户程序调用。但这个方法指针是有限制的,它规定好了所指向方法的返回值、参数个数以及各个参数的类型。因此,这把“钥匙”能打开蛋糕盒却打不开潘多拉之盒,感觉安全多了。
委托是对函数的封装可以当作给方法的特征指定一个名称。方法是将类型参数化,所谓类型参数化就是说该方法接受一个参数,而该参数是某种类型的参数,比如int、string等等;而委托是将方法参数化,也就是将方法作为一个参数传到一个委托中。
委托是一种引用方法的类型,一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托用关键字delegate来声明。事件是说在发生其他类或对象关注的事情时,类或对象可通过事件通知它们,事件对象用关键字event来声明。
委托与事件的协同合作,使得两个需要存在调用关系的类型,在各自的实现中不必编写实际的调用代码,它们只是通过一个事件和一个第三方的委托类型完成了消息的传递过程。这样两个类型之间不存在任何的紧密耦合,实现了“高聚合”和“低耦合”。
1.需求:
有一只Tom猫,每当他叫“喵,我是Tom.”的时候,两只小老鼠Jack和Dam就会说“猫来了,快跑吧!”。
2.分析:
该例子涉及两个类,Cat和Mouse。在Main函数中,当Cat的Shout方法触发时,Mouse就执行Run方法。如何让这两个方法相关联呢,在这里就要用到委托和事件了。
3.实现:
class Cat { private string name; public Cat(string name) { this.name = name; } //声明委托CatShoutEventHandler public delegate void CatShoutEventHandler(); //声明事件Catshout,它的事件类型是委托CatShoutEventHandler public event CatShoutEventHandler CatShout; //猫叫的方法 public void Shout() { Console.WriteLine("喵喵,我是{0}。", name); //当执行Shout方法时,若CatShout中有对象登记事件,则执行 if (CatShout != null) { CatShout(); } } }
class Mouse { public string name; public Mouse(string name) { this.name = name; } //老鼠逃跑的方法 public void Run() { Console.WriteLine("老猫来了,{0}快跑!", name); } }
static void Main(string[] args) { Cat cat = new Cat("Tom"); Mouse mouse1 = new Mouse("Jack"); Mouse mouse2 = new Mouse("Dam"); //将mouse的run方法通过实例化委托登记到事件catshout中 cat.CatShout += new Cat.CatShoutEventHandler(mouse1.Run); cat.CatShout += new Cat.CatShoutEventHandler(mouse2.Run); cat.Shout(); Console.Read(); }
"+="增加委托实例对象的意思。实例化委托有两种方法:
(1):直接将方法赋值[=]或者用“+=”给一个委托==>委托名 =[+=] 方法名
(2):委托本质也是一个类,只是一个特殊的类,所以我们也可以实例化一个委托对象通过委托构造函数来注册委托==》委托名对象名= new 委托名(方法名)
"-="移除委托。(以上使用无参数的委托事件,还可以添加参数)
4.效果:
5.理解:
学习要简单化,说实话委托和事件确实挺难理解的,我现在理解得还很肤浅。通过这个例子,我们可以这样认为,CatShoutEventHandler委托将方法CatShout和老鼠的Run联系在一起,当cat发生shout时,触发mouse发生run。使用委托分三步,定义、实例化、调用。学习是个循序渐进的过程,暂且这样理解吧。欢迎大家评论交流。
原文地址:http://blog.csdn.net/cyl_happygirl/article/details/24880743