C#每天进步一点--事件
事件:如果类型定义了事件成员,那么类型就可以通知其他对象发生了特定的事情。例如,Button类提供了一个名为Click的事件。应用程序中的一个或者多个对象可能想接收关于这个事件的通知,以便在Button被点击后采取操作。
下面我们利用一个例子来加深我们对事件的理解:假定现在要设计一个电子邮件应用程序,电子邮件到达时,用户可能希望将该邮件转发给传真机或其他设备。构建这个应用程序时,先设计一个MailManager的类型,他负责接收传入的电子邮件,MailManager类型公布一个NewMail的事件。其他类型,如Fax和Pager对象可登记对它们对这个事件的关注。
下面上代码:
第一步:定义类型来容纳所有需要发送给事件通知接收者的附加信息
internal class NewMailEventArgs : EventArgs{
private readonly String m_from,m_to,m_subject;
Public NewMailEventArgs(string from,string to,string subject){
m_from=from;m_to=to;m_subject=subject;
}
public string From{get{return m_from;}}
Public string To{get{return m_to;}}
Public string Subject{get{return m_subject;}}
}
注:EventArgs只是一个让其他类型继承的基类型。许多事件都没有附加的信息要传递,但在我们的场景中需要传递邮件信息,就构造NewMailEventArgs。
第二步:定义事件成员
internal class MailManager{
public event EventHandler<NewMailEventArgs> NewMail;
}
注:NewMail是这个事件的名称。事件成员的类型是EventHandler<NewMailEventArgs>,所以方法原型必须具有以下形式:
void MethodName(Object sender,NewMailEventArgs e);
第三步:定义负责引发事件的方法来通知事件的登记对象
internal class MailManager{
protected virtual void OnNewMail(NewMailEventArgs e){
//出于线程安全考虑,现在将委托字段的引用复制到一个临时字段中
EventHandler<NewMailEventArgs> temp = Interlocked.CompareExchange(ref NewMail,null,null);
//任何方法登记了对事件的关注,就通知他们
if(temp!=null) temp(this,e);
}
}
第四步:定义方法将输入转化为期望事件
internal class MailManager{
public void SimulateNewMail(string from,string to,string subject){
NewMailEventArgs e = new NewMailEventArgs(from,to,subject);
OnNewMail(e);
}
}
设计侦听事件类型,下面我们使用Fax类型来使用事件,上代码
internal sealed Class Fax{
public Fax(MailManager mm){
mm.NewMail += FaxMsg;
}
//新的电子邮件到达时,MailManager将调用这个方法
Private Void FaxMsg(object sender,NewMailEventArgs e){
Console.WriteLine("事件触发");
}
//执行这个方法,Fax对象将向NewMail事件注销自己对它的关注
Public Void Unregister(MailManager mm){
mm.NewMail -= FaxMsg;
}
}
注:C#编译器会将+=操作符翻译成以下代码来添加对象对事件的关注:
mm.add_NewMail(new EventHandler<NewMailEventArgs>(this.FaxMsg));
这样我们的例子就完成了,当有新的邮件收到时就会触发对邮件类事件关注的所有方法,即例子中的Fax中的FaxMsg方法。例子需要对大家理解事件有所帮助。
C#每天进步一点--事件的更多相关文章
- JavaScript中的this指向
this是谁 技术一般水平有限,有什么错的地方,望大家指正. this代指当前对象super调用父类的构造函数,应表会运网数物,加载驱动建立链接执行SQL处理结果,直到现在每想起这三点就能想起我上大学 ...
- 13 年的 Bug 调试经验总结
在<Learning From Your Bugs>一文中,我写了关于我是如何追踪我所遇到的一些最有趣的bug.最近,我回顾了我所有的194个条目(从13岁开始),看看有什么经验教训是我可 ...
- flex Bindable
[Bindable]大概又是Flex用得最多的元数据了.刚开始用用确实好简单,效率真是没的说.不过这几天用着却碰到了些问题,我自己搜集了些资料,想着有必要在blog里总结一下吧. 啥是元数据(meta ...
- 使用Chrome DevTools的Timeline和Profiles提高Web应用程序的性能
来源: http://www.oschina.net/translate/performance-optimisation-with-timeline-profiles 我们都希望创建高性能的Web应 ...
- 13 年的 Bug 调试经验总结(来自蜗牛学院)
在<Learning From Your Bugs>一文中,我写了关于我是如何追踪我所遇到的一些最有趣的bug. 最近,我回顾了我所有的194个条目,看看有什么经验教训是我可以学习的.下面 ...
- Android 开发第一项目——计算器的开发记录
2017.4.1 今天布局界面基本完成,现在写了一点事件绑定.计划是多用动态绑定,随时用随时改.关于布局方面,昨天弄到很晚,原因是Layout使用错误,用的自带的,没仔细看,预览的时候没有问题但是真机 ...
- JNI详解---从不懂到理解
转载:https://blog.csdn.net/hui12581/article/details/44832651 Chap1:JNI完全手册... 3 Chap2:JNI-百度百科... 11 C ...
- Rpgmakermv(24 )yep_coreengine
==左部为原文,右边我做了简要翻译=================================== Introduction and Instructions ================= ...
- 嵌入式码农的10年Bug调试经验,值得一看
下面这些都是我经历过的会导致难点bug的问题: 1.事件顺序.在处理事件时,提出下列问题会很有成效:事件可以以不同的顺序到达吗?如果我们没有接收到此事件会怎么样?如果此事件接连发生两次会怎么样?哪怕通 ...
随机推荐
- 在CentOS系统上将deb包转换为rpm包
转载自 http://www.heminjie.com/system/linux/1487.html deb文件格式本是ubuntu/debian系统下的安装文件,那么我想要在redhat/cento ...
- mingw-w64线程模型:posix vs win32(posix允许使用c++11的std:: thread,但要带一个winpthreads,可能需要额外dll)
我正在安装 mingw-w64 on Windows,有两个选项: win32线程和posix线程. 我知道win32线程和pthreads之间的区别,但是我不明白这两个选项之间的区别. 我怀疑如果我 ...
- Tcl package require Tk 出现没用的小方框
package require Tk wm withdraw . 当引用了tk的时候会出现一个tk的方框 , 下面那句话就是隐藏掉那个方框
- PAT练习题概览
PAT(pat.zju.edu.cn)是一个面向 C/C++程序的 Online Judge 系统.相比 ZOJ,HDOJ,POJ 等 ACM 题库,PAT 的题目非常基础,对于数据结构.算法的入门是 ...
- HSQL一个简短的引论
前言 在对dao层写測试类的时候,我们须要一个測试数据库,一般我们会是专门建立一个真实的測试数据库,可是有了HSQLDB事情就变得简单了起来. 正题 一.简单介绍: hsql数据库是一款纯Ja ...
- RabbitMq核心概念和术语
简介 越来越多的消息中间件很容易让人产生混淆,在学习一种消息中间件的时候,最好先了解他的几种抽象概念,方便你理解,明白了这些概念,你学习起来的时候也就得心应手,同时也是使用好RabbitMQ的基础. ...
- Gamma 函数与exponential power distribution (指数幂分布)
1. Γ(⋅) 函数 Γ(α)=∫∞0tα−1e−tdt 可知以下基本性质: Γ(α+1)=αΓ(α) Γ(1)=1 ⇒ Γ(n+1)=n! Γ(12)=π√ 2. 指数幂分布(exponential ...
- DDD实战3 领域层的设计
1.新建一个解决方案文件夹 取名Product 2.在Product解决方案文件夹下面创建一个.net core 类库项目 取名Product.Domain,引用项目DDD.Base项目 3.在类库下 ...
- WPF中如何选择合适的元数据标记?(英文)
原文:WPF中如何选择合适的元数据标记?(英文) FrameworkPropertyMetadataOptions Enumeration:Specifies the types of framewo ...
- AntDesign Form表单字段校验的三种方式
1.使用getFieldDecorator的rules规则 最简单的方法就是使用getFieldDecorator中的rules验证.rules中定义校验规则,message为校验不通过时的提示文字. ...