事件:如果类型定义了事件成员,那么类型就可以通知其他对象发生了特定的事情。例如,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#每天进步一点--事件的更多相关文章

  1. JavaScript中的this指向

    this是谁 技术一般水平有限,有什么错的地方,望大家指正. this代指当前对象super调用父类的构造函数,应表会运网数物,加载驱动建立链接执行SQL处理结果,直到现在每想起这三点就能想起我上大学 ...

  2. 13 年的 Bug 调试经验总结

    在<Learning From Your Bugs>一文中,我写了关于我是如何追踪我所遇到的一些最有趣的bug.最近,我回顾了我所有的194个条目(从13岁开始),看看有什么经验教训是我可 ...

  3. flex Bindable

    [Bindable]大概又是Flex用得最多的元数据了.刚开始用用确实好简单,效率真是没的说.不过这几天用着却碰到了些问题,我自己搜集了些资料,想着有必要在blog里总结一下吧. 啥是元数据(meta ...

  4. 使用Chrome DevTools的Timeline和Profiles提高Web应用程序的性能

    来源: http://www.oschina.net/translate/performance-optimisation-with-timeline-profiles 我们都希望创建高性能的Web应 ...

  5. 13 年的 Bug 调试经验总结(来自蜗牛学院)

    在<Learning From Your Bugs>一文中,我写了关于我是如何追踪我所遇到的一些最有趣的bug. 最近,我回顾了我所有的194个条目,看看有什么经验教训是我可以学习的.下面 ...

  6. Android 开发第一项目——计算器的开发记录

    2017.4.1 今天布局界面基本完成,现在写了一点事件绑定.计划是多用动态绑定,随时用随时改.关于布局方面,昨天弄到很晚,原因是Layout使用错误,用的自带的,没仔细看,预览的时候没有问题但是真机 ...

  7. JNI详解---从不懂到理解

    转载:https://blog.csdn.net/hui12581/article/details/44832651 Chap1:JNI完全手册... 3 Chap2:JNI-百度百科... 11 C ...

  8. Rpgmakermv(24 )yep_coreengine

    ==左部为原文,右边我做了简要翻译=================================== Introduction and Instructions ================= ...

  9. 嵌入式码农的10年Bug调试经验,值得一看

    下面这些都是我经历过的会导致难点bug的问题: 1.事件顺序.在处理事件时,提出下列问题会很有成效:事件可以以不同的顺序到达吗?如果我们没有接收到此事件会怎么样?如果此事件接连发生两次会怎么样?哪怕通 ...

随机推荐

  1. 【22.70%】【codeforces 591C】 Median Smoothing

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  2. 【13.91%】【codeforces 593D】Happy Tree Party

    time limit per test3 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  3. postman VS restlet client基本使用

    postman与restlet都是使用的google浏览器的插件(出不去自行解决,you get!),此两款软件的强大这里就不在赘述了,postman的网上说明很多,restlet的中文配置很少了.这 ...

  4. 调试分析工具 (C/C++)

    一.静态分析工具 cppcheck cppcheck主要用于对C/C++源代码进行分析检查的一个开源工具,可以用来检测未使用的变量.越界访问.内存泄漏等问题. 使用方法 cppcheck --enab ...

  5. ASP.NET中进度条的简单应用

    <html xmlns="http://www.w3.org/1999/xhtml" id="mainWindow"> <head> & ...

  6. git commit 报错 There was a problem with the editor 'vi'

    今天提交代码git  commit -a的时候出现了这个错误 上网查了一下,说是Vim的返回值出错了,出错的原因还在翻译英文, 先贴出解决方案吧 git config --global core.ed ...

  7. 允许Android对于飞行模拟器

    Android模拟器是公认的慢,并且不是一般的慢,即使在高性能的PC上,跟开发环境没关系,由于它就是慢.可是我们又必须使用模拟器,比方在測试Android不同版本号的兼容性时,或者在測试不同屏幕尺寸的 ...

  8. Go 在 Windows 上用户图形界面 GUI 解决方案 Go-WinGUI 国产(使用cef 内核)

    Go 在 Windows 上用户图形界面 GUI 解决方案 Go-WinGUI 国产 Go 在服务端的优势不容置疑,但是在桌面应用上却没有好的 GUI 支持,本项目是 Go 语言在 Windows 上 ...

  9. WPF Bind 绑定

    原文:WPF Bind 绑定 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/koloumi/article/details/74332515 用过W ...

  10. QT定时器的两种应用(QObject就有timerEvent事件,一种什么样的居心呢?)

    QT中定时器的使用方法(1)重载timerEvent(QTimerEvent *)函数,然后再在类的构造函数中设置时间间隔   startTimer(50);//单位为毫秒(2)在类的构造函数中设定如 ...