委托与事件(一)——C#版本

时间:2022-03-21 01:28:21

什么是委托与事件

  委托是对函数的封装,可以当作给方法的特征指定一个名称。而事件则是委托的一种特殊形式,当发生有意义的事情时,事件对象处理通知过程。
  委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为

为什么要用委托与事件

  用例子来说明为什么必须要用委托与事件。

V1_猫叫老鼠跑,依赖:

public class Client{
	public static void main(string[] args){
		Cat cat = new Cat("Tom");
		cat.Shout();
	}
}


public class Cat{
	private string name;
	public Cat(string name){
		this.name = name;
	}
	public void Shout(){
		Console.WriteLine("喵,我是{0}",name);
		Mouse mouse = new Mouse("Jerry");
		mouse.Run();
	}
}

public class Mouse{
	private string name;
	public Mouse(string name){
		this.name = name;
	}
	public void Run(){
		Console.WriteLine("猫来了,{0}快跑",name);
	}
}

以上代码对应类图:
委托与事件(一)——C#版本
  在V1中,由图可以明显的看出来,猫直接依赖了老鼠。但咱们结合现实生活来看,猫和老鼠是与生俱来的天敌,他们互不认识,但只要猫一出现,老鼠肯定会跑。所以前提是猫不认识老鼠,但老鼠听到猫叫会跑。那咱们的代码写的就有问题了,在猫类的猫叫方法中直接实例化了老鼠类,表示猫认识老鼠,猫叫是通知老鼠跑的意思,直接产生了猫叫老鼠跑关系。如何解开这种关系,此时就引入了委托与事件,让我们拭目以待!

V2_猫叫老鼠跑,事件与委托:

public class client{
	public static void main(string[] args){
		Cat cat = new Cat("Tom");
		Mouse mouse = new Mouse("Jerry");
		CatShout += new cat.CatShoutEventHandler(mouse.run);
		cat.Shout();
		Console.Read();
	} 
}

public 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("喵,我是{0}",name);
		if(CatShout != null){
			CatShout();
		}
	}
}

public class Mouse{
	private string name;
	public Mouse(string name){
		this.name=name;
	}
	public void Run(){
		Console.WriteLine("猫来了,{0}快跑",name);
	}
}

以上代码对应类图:
委托与事件(一)——C#版本
  在类图中,我们可以明显的看出猫和老鼠类没有关系了,实际上他们是通过委托与事件产生了联系。在主函数中CatShout += new cat.CatShoutEventHandler(mouse.run);表示将Mouse的Run方法通过实例化委托Cat.CatShoutEventHandler 登记到Cat的事件CatShout当中。其中“+=”表示“add CatShout”的意思。解决了我们第一版代码出现的问题,对猫和老鼠进行了解耦合操作。

事件与委托概念和V2_猫叫老鼠跑代码做映射:

  为了让大家能更清楚的认识到委托与事件,我做了一个概念对应代码的分析,供大家理解:
将此句对应上代码:委托是对函数的封装,可以当作给方法的特征指定一个名称。而事件则是委托的一种特殊形式,当发生有意义的事情时,事件对象处理通知过程。

  1. 委托是对函数的封装:Cat.CatShoutEventHandler (mouse1.Run);——将老鼠跑的方法封装到了CatShoutEventHandler委托中。
  2. 可以当作给方法的特征指定一个名称:CatShoutEventHandler;——在声明委托CatShoutEventHandler时已经确定了,可以根据业务随意起名。
  3. 事件则是委托的一种特殊形式:public event CatShoutEventHandler CatShout;
  4. 当发生有意义的事情时:if(CatShout != null)——如果此事件里登记了委托,才会继续执行
  5. 事件对象处理通知过程:CatShout();——自我调用,此时去执行事件,触发老鼠跑。

将此句对应上代码:委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为

  1. 委托是一种引用方法的类型:public delegate void CatShoutEventHandler();
  2. 一旦为委托分配了方法,委托将与该方法具有完全相同的行为:Cat.CatShoutEventHandler (mouse1.Run)

  学无止境,我们不仅需要能写出符合业务的代码,还要写出和实际相符合的代码来,我们需要不断地练习实践才可能真正成为优秀的软件工程师!