写在前面的话:一直对委托和事件一知半解,正好借着学设计模式的机会又学习了一番委托和事件,好像有点感觉了~
委托:
委托是一种引用方法的类型,可以为委托分配一个方法,委托将和该方法具有完全相同的行为(委托是对函数的封装)
委托的声明:
委托对象用关键字delegate声明
声明一个无参数委托:
public delegate void AHandler();
声明一个带参数委托:
public delegate void BHandler(object sender,SonEventArgs args);
事件:
委托的一种特殊形式,在发生其他类或对象关注的事情时,类或对象可通过事件通知它
声明一个事件(事件类型为委托):
public event AHandler AEvent;
public event BHandler BEvent;
为事件添加委托:
public void FunctionA(){//方法A}
AEvent += new AHandler(FunctionA);
public void FunctionB(){//方法B}
BEvent += new BHandler(FunctionB);
实例:
背景:别墅中有一只猫和两只老鼠。设定猫有两种叫声,第一种叫声不带有自己的名字,第二种叫声会带上自己的名字;设定老鼠听到猫的叫声就会跑,根据叫声的不同会有两种跑法,第一种是没听到猫的名字,从厨房跑,第二种是听到猫的名字,从阁楼跑。
首先创建两个类,分别是猫和老鼠。
猫的类中包含两种叫声,每种叫声均声明一个委托和该委托对应的事件,再通过一个方法来调用该事件。(区别在于委托是否带参数)
class Cat
{
private string name;
public Cat(string name)
{
this.name = name;
}
//不自报名字的叫声(不带参数的委托)
public delegate void NoNameShoutEventHandler();
public event NoNameShoutEventHandler NoNameShoutToMouse;
public void NoNameShout()
{
Console.WriteLine("喵喵!你们的大魔王来了!");
//if (NoNameShoutToMouse != null)
// NoNameShoutToMouse();
NoNameShoutToMouse?.Invoke();//简化写法
}
//自报名字的叫声(带参数的委托)
public delegate void WithNameShoutEventHandler(object sender, CatShoutEventArgs e);
public event WithNameShoutEventHandler WithNameShoutToMouse;
public void WithNameShout()
{
Console.WriteLine("喵喵!我{0}大魔王又来了!", name);
//if (WithNameShoutToMouse != null)
// WithNameShoutToMouse();
CatShoutEventArgs eventArgs = new CatShoutEventArgs();
eventArgs.Name = name;
WithNameShoutToMouse?.Invoke(this, eventArgs);//简化写法
}
}
老鼠的类在那个包含两种逃跑方式(跑的时候会提到自己的名字)
class Mouse
{
private string name;
public Mouse(string name)
{
this.name = name;
}
public void Run()
{
Console.WriteLine("这是哪只猫?不管了,我{0}先跑一步啦,从厨房跑~",name);
}
public void Run(object other, CatShoutEventArgs e)
{
Console.WriteLine("{0}又来了,我{1}先跑一步啦,从阁楼跑~",e.Name,name);
}
}
猫的类中自报名字的委托传递了两个参数,第一个参数是object类型的,一般用来传递事件触发的对象,第二个参数CatShoutEventArgs是继承了EventArgs的子类(EventArgs是包含事件数据的类的基类),写一个子类的目的是既能传递包含事件的数据还能自己定义其他传递的内容。
CatShoutEventArgs类的内容如下:
class CatShoutEventArgs : EventArgs
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
在使用的时候非常简单:
首先实例化出一只猫和两只老鼠:
Cat cat = new Cat("Tom");
Mouse mouse1 = new Mouse("Jerry");
Mouse mouse2 = new Mouse("Jack");
接着将两只老鼠的逃跑方法委托给猫叫的这个事件上
cat.NoNameShoutToMouse += new Cat.NoNameShoutEventHandler(mouse1.Run);
cat.NoNameShoutToMouse += new Cat.NoNameShoutEventHandler(mouse2.Run);
cat.WithNameShoutToMouse += new Cat.WithNameShoutEventHandler(mouse1.Run);
cat.WithNameShoutToMouse += new Cat.WithNameShoutEventHandler(mouse2.Run);
然后让猫叫就可以啦~
Console.WriteLine("猫第一次叫,没带上自己的名字:");
cat.NoNameShout();
Console.ReadLine();
Console.WriteLine("猫第二次来,还带上了自己的名字:");
cat.WithNameShout();
Console.ReadLine();
运行效果:
github项目源码在此:委托与事件——猫抓老鼠