相关概念 定义:事件是用于通知其他对象发生了本对象发生了特定的事情的类型成员。
说明:事件是.NET类型成员中相对较为难以理解和实践的一个成员,因为事件的定义不是继承自基础的数据类型,而是对委托(delegate)的封装。所以,在了解事件之前,你需要先了解一点委托。
应用场景:事件的应用场景非常广泛,其中最常见的场景是在各个前端控件中的大量触发事件设计。原因是因为
意义:事件成员的使用有利于在程序中对面向对象原则的实现。例如类型的单一职责原则,控制反转原则。设想如果前端控件不能抽象出大量丰富的事件,那几乎不能将前端的UI元素与业务逻辑脱钩。程序必然高度耦合。
设计模式的应用:经典设计模式中的观察者模式就非常依赖于对事件成员的设计而实现。
本章将通过设计一个电子邮件到达时,触发事件的场景来解析对事件提供者和订阅者类型的设计。案例来源于《CLR Via C#》一书。
事件提供者类型的设计 一. 定义类型来容纳所有需要发送给事件订阅者的附加信息 目标:定义一个类型用于向事件的订阅者传递信息
方法:继承默认的System.EventArgs类型,实现简单的需要传递信息的字段,属性以及实例构造器成员。示例如下:
复制代码 代码如下:
using System;
using System.Linq;
namespace ConsoleTest
{
public class NewMailEventArgs : EventArgs
{
private readonly string from, to, subject;
public NewMailEventArgs(string from, string to, string subject)
{
this.from = from;
this.to = to;
this.subject = subject;
}
public string Subject
{
get
{
return this.subject;
}
}
public string To
{
get
{
return this.to;
}
}
public string From
{
get
{
return this.from;
}
}
}
}
二. 定义事件成员 目标:在事件提供者类型中定义一个事件成员,用于事件订阅者对象的注册。
方法:封装一个自定义委托,来提供事件处理方法的模板;或者实现一个System.EventHandler的泛型类型来达到一样的效果。(EventHandler是一个默认提供的已封装的委托)。两种方法的示例分别如下:
方法一:
复制代码 代码如下:
public delegate void NewMailHandler(object e, NewMailEventArgs args);
public class MailManager
{
public event NewMailHandler NewMail;
}
方法二:
复制代码 代码如下:
public class MailManager
{
public event EventHandler<NewMailEventArgs> NewMail;
}
为什么这两种方法能够达到同样的效果,查看一下System.EventHandler的定义就能知晓:
复制代码 代码如下:
namespace System
{
// 摘要:
// 表示将处理事件的方法。
//
// 参数:
// sender:
// 事件源。
//
// e:
// 一个包含事件数据的 System.EventArgs。
//
// 类型参数:
// TEventArgs:
// 由该事件生成的事件数据的类型。
[Serializable]
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
}
三. 定义一个统一触发事件的方法入口来通知事件的订阅对象 目标:在事件提供者类型中定义一个方法成员,用来统一的引发目标事件。
说明:为了保证这个方法只能在本类型及派生类型中调用,我们需要将方法修饰为protected, 为了让派生类型可以重写这个方法,我们需要将该方法修饰为virtual
意义:这个统一入口方法的意义在于,能够统一维护触发事件的方式,并且能够确保事件调用的线程安全性。(避免在不同的线程触发时,事件订阅者的状态不同步)
示例如下:
复制代码 代码如下:
public class MailManager
{
public event EventHandler<NewMailEventArgs> NewMail;
protected virtual void OnNewMail(NewMailEventArgs e)
{
//处于线程安全的考虑,现在将对委托字段的引用复制到一个临时字段中
EventHandler<NewMailEventArgs> temp = System.Threading.Interlocked.CompareExchange
(ref NewMail, null, null);
//如果有事件订阅者对象的存在,则通知他们,事件已触发
if (temp != null)
temp(this, e);
}
}
四. 在所有需要触发事件的业务方法中,调用第三步中定义的方法 目标:在类型中还需要有一个业务方法,来将业务中的场景转化为事件触发。。
方法:在任意需要的业务方法中,直接调用第三步的方法就可以了,不过需要实现封装一个传递信息的类型。
示例如下:
复制代码 代码如下:
public class MailManager
{
public event EventHandler<NewMailEventArgs> NewMail;
protected virtual void OnNewMail(NewMailEventArgs e)
{
//处于线程安全的考虑,现在将对委托字段的引用复制到一个临时字段中
EventHandler<NewMailEventArgs> temp = System.Threading.Interlocked.CompareExchange
(ref NewMail, null, null);
//如果有事件订阅者对象的存在,则通知他们,事件已触发
if (temp != null)
temp(this, e);
}
public void SimulateNewMail(string from, string to, string subject)
{
//构造一个对象来封装向传给事件订阅者的信息
NewMailEventArgs e = new NewMailEventArgs(from, to, subject);
//触发事件引发的入口方法
OnNewMail(e);
}
}
事件订阅者类型的设计 一. 定义类型来订阅和侦听事件 目标:设计一个传真类型Fax类来侦听NewMail事件。
说明:Fax类型中需要具备对NewMail事件的订阅和取消订阅的方法。示例如下:
复制代码 代码如下:
internal sealed class Fax
{
private MailManager mailManager;
public Fax(MailManager mm)
{
this.mailManager = mm;
}
public void Register()
{
mailManager.NewMail += new EventHandler<NewMailEventArgs>(FaxMsg);
}
void FaxMsg(object sender, NewMailEventArgs e)
{
Console.WriteLine("Fax mail message");
Console.WriteLine("From = {0}, To = {1}, Subject = {2}", e.From, e.To, e.Subject);
}
public void Unregister()
{
mailManager.NewMail -= FaxMsg;
}
}
相关推荐:
SEO运维:提升网站排名的核心战略,邢台网站建设优化建站
为什么越来越多的人选择在知乎发布文章?这里面的机会你可能还没发现!,潍坊关键词排名提升
AI代谢文章:从灵感到成果的创作革命
seo经理做什么的,seo经理招聘 ,盲人ai眼镜
SEO中的别类词:提升排名,轻松超越竞争对手,ai插画生肖
AI撰写率:让创作变得更高效,助力内容产业腾飞,人力ai
ChatGPT画布打不开?如何解决这一常见问题?,Ai怎么储存为Ai格式在桌面
AI免费写文章:让创作变得轻松高效
ChatGPT无法访问原因分析及解决方案,斑马ai报道
SEO优化如何为网站做好关键词研究和优化,ai直通
360排名优化价格:打造高效网络营销的制胜法宝,ai换脸刘浩存自wei
seo适合什么人做,哪种seo做得好 ,晋城ai论文写作免费
seo涉及什么内容,seo主要包括 ,法医使用ai
seo读什么书,seo是哪个专业的 ,亚洲9ai吧
SEO优化:提升网站流量的终极指南,揭阳网站快速推广
如何用AI改文章,让写作更高效、精准,提升内容质量
SEO建站,开启网站优化的全新篇章!,网络营销推广合作方式
seo适合看什么书,自学seo书籍推荐 ,ai少女 刻晴
seo进阶买什么书运营,seo入门难吗 ,没有ai软件怎么打开ai图片
ChatGPT怎么突然不能打开了?你需要了解的原因与解决办法,ai写作有什么问题吗怎么解决
目前AI软件有哪些?智能新时代的必备工具
OpenAI推出的GPT-4Turbo大幅降低了AI应用成本,推动了AI技术的普及化,ai*版
SEO薪资这些,你也能月入过万!,天水网站建设公司
SEO建议:如何通过优化提升网站流量,赢得市场竞争,自媒体网站免费推广平台
什么是蜘蛛弛?揭秘这个SEO优化背后的神秘工具,南沙seo优化排名价格
seo需要什么人才,seo需要做什么工作 ,探索ai照片
亚马逊seo是什么公司的,“亚马逊” ,ai玩底特律
seo要什么条件,seo都需要做什么 ,交互ai求职
【BVIP尊享体验:超越奢华,开启专属未来】,珠宝网站建设思路
SEO站外优化策略:提升网站排名的关键因素,遵义公司网站推广
什么叫改写-解读“改写”背后的艺术与技巧,网站制作建设模板图片
什么是seo发外链,seo外链类型有哪些 ,小小苏ai
AI批量文章工具,让写作变得高效与轻松,cs机器人ai
OpenAIGPTChatSoraOpenAIChatGPT服务在中断数小时后已恢复,ai视图线稿
企业关键字-助力企业成功的隐形动力,闽侯县企业网站建设
英语日记AI生成:轻松提升英语水平的智能助手
SEO优化:让你的网站在竞争中脱颖而出,临沧seo代理
ChatGPT国内版:为中国用户量身定制的智能助手,开启AI新纪元,ai文章赚钱
未来的效率利器AI软件下载AI,助您轻松驾驭智能世界
如何利用AI生成高质量文章,提升写作效率与创意?
seo网络培训是什么,seo工作培训会培训啥 ,ai长投影字
2025年SEO最新技术:让你的网站脱颖而出!,ai少女特色
优化服务网-提升客户体验,打造全方位智慧服务平台,东莞网站建设员招聘信息
“赞片CMS”-让你的*站点管理更高效、便捷,日照seo平台
怎么用AI写出高质量科普文章?揭秘新时代创作利器!
AI撰写工具的无限可能,让内容创作更高效、更精彩!
在线AI写文:开启高效创作新时代
SEO无限:如何利用SEO技术实现网站流量爆发?,网站建设总监
打造内容创作新高度:文章扩写AI的革命性优势
常用AI工具,高效智能生活