设计模式学习笔记二:面向对象基础六之委托与事件
委托
委托作为函数的封装,可以当作给方法的特征指定一个名称。
事件
事件则是委托的一种特殊形式,当发生有意义的事情时,事件对象处理通知过程。事件其实就是设计模式中观察者模式在.net中的一种实现方式。
下面看实例来学习,实例的需求是,有一只老猫叫Tom,有两只老鼠叫Jerry和Jack,Tom只要一叫‘嘧,我是Tom!’,两只老鼠就说‘老猫来了,快跑!’。通过分析应该有Cat和Mouse类,在Main函数中执行,但Cat的Shout方法触发时,Mouse就执行Run方法,不过这里如何让Cat的Shout触发时,通知两只老鼠呢?显然老猫不会认识老鼠,也不会主动通知老鼠‘我来了,你们快跑’。所以Cat类中,是不应该关联Mouse类的。此时用委托事件的方式就是最好的处理方法了。
委托是一种引用方法的类型。一旦委托分配了方法,委托将与该方法具有完全相同的行为。委托对象用关键词delegate来声明。而事件是说在发生其他类或对象关注的事情是时,类或对象可通过事件通知他们。事件对象用event关键词声明。
Cat类:
“+="就是增加委托实例对象的意思。相应的"-="就是移除委托实例的意思。"-="就是"remove_CatShout()"的含义,使用它,就等于减少一个需要触发事件是通知大对象。
运行结果:

EventArgs是包含事件数据的类的基类.换句话这个类的作用就是用来在事件触发时传递数据用的。
新增的CatShoutEventArgs类:
修改后的Cat类:
修改后的Mouse类:
Main不用修改,请看现在运行结果:
委托作为函数的封装,可以当作给方法的特征指定一个名称。
事件
事件则是委托的一种特殊形式,当发生有意义的事情时,事件对象处理通知过程。事件其实就是设计模式中观察者模式在.net中的一种实现方式。
下面看实例来学习,实例的需求是,有一只老猫叫Tom,有两只老鼠叫Jerry和Jack,Tom只要一叫‘嘧,我是Tom!’,两只老鼠就说‘老猫来了,快跑!’。通过分析应该有Cat和Mouse类,在Main函数中执行,但Cat的Shout方法触发时,Mouse就执行Run方法,不过这里如何让Cat的Shout触发时,通知两只老鼠呢?显然老猫不会认识老鼠,也不会主动通知老鼠‘我来了,你们快跑’。所以Cat类中,是不应该关联Mouse类的。此时用委托事件的方式就是最好的处理方法了。
委托是一种引用方法的类型。一旦委托分配了方法,委托将与该方法具有完全相同的行为。委托对象用关键词delegate来声明。而事件是说在发生其他类或对象关注的事情是时,类或对象可通过事件通知他们。事件对象用event关键词声明。
public delegate void CatShoutEventHandler();
public event CatShountEventHandler CatShout;
上面就声明了一个委托,委托名称叫CatShoutEventHandler,而这个委托所代替的方法是无参数、无返回值的方法。然后声明了一个对外公开的public 事件CatShout,他的事件类型是委托CatShoutEventhandler。表明事件发生时,执行被委托的方法。下面看完整的实践代码:public event CatShountEventHandler CatShout;
Cat类:
public 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中有对象登记事件,则执行CatShout();
if (CatShout != null)
{
CatShout();
}
}
}
Mouse类:{
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中有对象登记事件,则执行CatShout();
if (CatShout != null)
{
CatShout();
}
}
}
public class Mouse
{
private string name;
public Mouse(string name)
{
this.name = name;
}
/// <summary>
/// 逃跑的方法
/// </summary>
public void Run()
{
Console.WriteLine("老猫来了,{0}快跑!",name);
}
}
main:{
private string name;
public Mouse(string name)
{
this.name = name;
}
/// <summary>
/// 逃跑的方法
/// </summary>
public void Run()
{
Console.WriteLine("老猫来了,{0}快跑!",name);
}
}
static void Main(string[] args)
{
//实例化老猫Tom以及老鼠Jerry和Jack
Cat cat = new Cat("Tom");
Mouse mouse1 = new Mouse("Jerry");
Mouse mouse2 = new Mouse("Jack");
//表示将Mouse的Run方法通过实例化委托Cat.CatShoutEventHandler登记到Cat的事件CatShout()当中,“+=”表示“add_CatShout”
cat.CatShout += new Cat.CatShoutEventHandler(mouse1.Run);
cat.CatShout += new Cat.CatShoutEventHandler(mouse2.Run);
cat.Shout();
Console.Read();
}
说明:new Cat.CatShoutEventHandler(mouse1.Run)的含义是实例化一个委托,而委托的实例其实就是Mouse类的Run方法。而‘cat.CatShout += ’表示的就是‘cat.add_CatShout(new Cat.CatShoutEventHandler(mouse1.Run)'的意思。{
//实例化老猫Tom以及老鼠Jerry和Jack
Cat cat = new Cat("Tom");
Mouse mouse1 = new Mouse("Jerry");
Mouse mouse2 = new Mouse("Jack");
//表示将Mouse的Run方法通过实例化委托Cat.CatShoutEventHandler登记到Cat的事件CatShout()当中,“+=”表示“add_CatShout”
cat.CatShout += new Cat.CatShoutEventHandler(mouse1.Run);
cat.CatShout += new Cat.CatShoutEventHandler(mouse2.Run);
cat.Shout();
Console.Read();
}
“+="就是增加委托实例对象的意思。相应的"-="就是移除委托实例的意思。"-="就是"remove_CatShout()"的含义,使用它,就等于减少一个需要触发事件是通知大对象。
运行结果:
EventArgs是包含事件数据的类的基类.换句话这个类的作用就是用来在事件触发时传递数据用的。
新增的CatShoutEventArgs类:
public class CatShoutEventArgs:EventArgs
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
修改后的Cat类:
public class Cat
{
private string name;
public Cat(string name)
{
this.name = name;
}
//声明委托CatShoutEventHandler,此时委托所代表的方法有两个参数,object参数和CatShoutEventArgs参数
public delegate void CatShoutEventHandler(object sender, CatShoutEventArgs args);
//声明事件CatShout,他的事件类型是委托CatShoutEventHandler
public event CatShoutEventHandler CatShout;
public void Shout()
{
Console.WriteLine("嘧,我是{0}。",name);
//表明但执行Shout()方法时,如果CatShout中有对象登记事件,则执行CatShout();
if (CatShout != null)
{
//声明并实例化了一个CatShoutEventArgs,并给name属性赋值为猫的名字
CatShoutEventArgs e = new CatShoutEventArgs();
e.Name = this.name;
//当事件触发时,通知所登记的对象,并将发送通知的自己以及需要的数据传递过去
CatShout(this, e);
}
}
}
{
private string name;
public Cat(string name)
{
this.name = name;
}
//声明委托CatShoutEventHandler,此时委托所代表的方法有两个参数,object参数和CatShoutEventArgs参数
public delegate void CatShoutEventHandler(object sender, CatShoutEventArgs args);
//声明事件CatShout,他的事件类型是委托CatShoutEventHandler
public event CatShoutEventHandler CatShout;
public void Shout()
{
Console.WriteLine("嘧,我是{0}。",name);
//表明但执行Shout()方法时,如果CatShout中有对象登记事件,则执行CatShout();
if (CatShout != null)
{
//声明并实例化了一个CatShoutEventArgs,并给name属性赋值为猫的名字
CatShoutEventArgs e = new CatShoutEventArgs();
e.Name = this.name;
//当事件触发时,通知所登记的对象,并将发送通知的自己以及需要的数据传递过去
CatShout(this, e);
}
}
}
修改后的Mouse类:
public class Mouse
{
private string name;
public Mouse(string name)
{
this.name = name;
}
/// <summary>
/// 逃跑的方法
/// </summary>
public void Run(object sender,CatShoutEventArgs args)
{
Console.WriteLine("老猫{0}来了,{1}快跑!",args.Name,name);
}
}
{
private string name;
public Mouse(string name)
{
this.name = name;
}
/// <summary>
/// 逃跑的方法
/// </summary>
public void Run(object sender,CatShoutEventArgs args)
{
Console.WriteLine("老猫{0}来了,{1}快跑!",args.Name,name);
}
}
Main不用修改,请看现在运行结果:
关注 熵减黑客 ,一起学习成长

分类:
设计模式
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端