c# 委托与事件(一)
一直觉得委托与事件很神秘,看了好几次书,一直在明白、糊涂两种状态中来回颠倒。其实一直没搞明白几个问题:
1. 为什么要用为委托与事件?(delegage, event)
2.什么时候用委托与事件?
3.委托与事件一定是同时出现吗?若不是,什么时候用委托与事件,什么时候只用委托?
4. 怎么使用委托与事件?
在《大话设计模式》这本书中,通过一个猫和老鼠的例子来说明委托与事件。有一只猫叫Tom,还有两只老鼠分别叫jerry 和jack, Tom只要叫一声“喵,我是Tom”, 两只老鼠就说“老猫来了,
为了实现这个场景,我们设计两个类,分别是Mouse 和Cat, 两个类中分别有Run()和Shout()。现在的问题是怎么把两个完全不相关的类中的两个方法关联起来,实现一个类中方法的执行时,自动触发另一个类中的方法呢?
这时候就该委托出场了。至于书本上的委托概念暂时先不说,先看代码如何实现的:
class Cat { private string name; public Cat(string name) { this.name = name; } public delegate void CatShoutEventHandler(); // 申明一个委托,相当于定义一个类, 委托的参数类型,返回值类型决定了该委托类型事件的参数类型和返回值类型。 public event CatShoutEventHandler CatShout; // 定义一个委托类型的事件,相当于实例化一个类的对象 public void Shout() {
Console.WriteLine("miu, i am {0}",name); if(CatShout!= null) // 在其他类中可以给这个委托事件绑定行为。如果事件被绑定了行为,CatShout就不为空。 { CatShout(); // 关联事件,实际上是调用绑定到这个事件上的方法。 } } } class Mouse { private string name; public Mouse(string name) { this.name = name; } public void Run() { Console.WriteLine("Cat is coming,{0} is hurry to run", name); } } class DelegateTest { public static void Main() { Cat cat = new Cat("Tom"); Mouse mouse1 = new Mouse("Jerry"); Mouse mouse2 = new Mouse("Jack"); cat.CatShout += mouse1.Run; // 原型是: cat.CatShout += new CatShoutEventHandler(mouse1.Run) 将Mouse的Run方法通过实例化委托登记到cat的事件中。 cat.CatShout += mouse2.Run; cat.Shout(); Console.Read(); } }
单步调试,可以看到委托是如何被调用的。运行结果:
miu, i am Tom
Cat is coming,Jerry is hurry to run
Cat is coming,Jack is hurry to run
通过这个例子,开始提到的大部分问题都找到了答案。现在还有一个问题是什么时候单独使用委托呢?
其实事件是对委托的封装,如果定义了一个委托类型的事件,可以使用+=符号给一个委托绑定多个行为,如果没有定义事件,则一个委托只能绑定到一个行为上。如在上面的基础上修改Cat,及Main():
class Cat {
private string name;
public Cat(string name) { this.name = name; } public delegate void CatShoutEventHandler(); //定义一个委托类型 public CatShoutEventHandler CatShout; //申明一个委托 public void Shout() { if(CatShout!= null) { CatShout(); } } } class DelegateTest { public static void Main() { Cat cat = new Cat("Tom"); Mouse mouse1 = new Mouse("Jerry"); Mouse mouse2 = new Mouse("Jack"); cat.CatShout = mouse1.Run; // 委托绑定一个行为 cat.Shout(); Console.Read(); } }
浙公网安备 33010602011771号