事件是类型的一个成员,用来在事情发生的时候通知注册了该事件的成员。

事件和观察者模式十分的相似,所以事件应该提供如下几种能力

1.能让对象的方法登记对他的关注

2.能让对象的方法取消对他的关注

3.能在事件发生的时候将通知发送给方法

在C#中的某个类中定义一个事件使用如下语句

public event EventHandler<EventArgs> SomeEvent;

其中EventHandler<EventArgs>是一泛型委托,在System命名空间下,委托的定义为

public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
其中TEventArgs是这个委托所需要定义的参数,应该从System.EventArgs派生,不过你要是在想传一个字符串什么的,确实也是没问题的。一般这个变量中会传递事件希望通知给事件订阅者的一些信息。
我们可以看见这个类什么都没有做,只是提供一种约束
    // 摘要:
// System.EventArgs 是包含事件数据的类的基类。
[Serializable]
[ComVisible(true)]
public class EventArgs
{
// 摘要:
// 表示没有事件数据的事件。
public static readonly EventArgs Empty; // 摘要:
// 初始化 System.EventArgs 类的新实例。
public EventArgs();
}

下面我们来设计如下常景。
我们需要一个自动回复机器人,当接收到信息中心传递来的消息后,我们需要回复'xxx,你好',xxx这个是发消息人,将通过EventArgs传过来
首先,我们需要一个信息中心类,有登记方法,取消登记,通知的功能
internal class MessageSender
{
//一个类型为委托的私有字段,这个字段维护了一个委托列表
private EventHandler<NewMessageEventArgs> m_NewMessage;
//一个事件成员,用来给外部方法登记和取消登记
public event EventHandler<NewMessageEventArgs> NewMessage
{
add
{
m_NewMessage += value;
}
remove
{
m_NewMessage -= value;
}
}
//通知订阅对象,有新消息到了
public void OnNewMessage(NewMessageEventArgs e)
{
if(m_NewMessage!=null)
{
m_NewMessage(this,e);
}
}
}

还需要定义一个事件参数类,用来传递消息发送人的名称

 //EventArgs类,携带发送消息的人的名称传递给事件订阅者
internal sealed class NewMessageEventArgs:EventArgs
{
private readonly String m_from;
public String From{get;}
}

现在定义两个消息订阅类,分别提供各自的方法来订阅消息发送事件

internal class JustSayHello
{
public JustSayHello(MessageSender ms)
{
ms.NewMessage += sayHello;
}
private void sayHello(object sender,NewMessageEventArgs e)
{
Console.WriteLine("Hello {0}",e.From);
}
public void unRegistered(MessageSender ms)
{
ms.NewMessage -= sayHello;
}
}
internal class JustSayAloha
{
public JustSayAloha(MessageSender ms)
{
ms.NewMessage += sayAloha;
}
private void sayAloha(object sender, NewMessageEventArgs e)
{
Console.WriteLine("Aloha {0}", e.From);
}
public void unRegistered(MessageSender ms)
{
ms.NewMessage -= sayAloha;
}
}

然后在静态方法中调用,

static void Main(string[] args)
{
MessageSender ms = new MessageSender();
NewMessageEventArgs e = new NewMessageEventArgs("ailijima");
JustSayHello jsh = new JustSayHello(ms);
JustSayAloha jsa = new JustSayAloha(ms);
ms.OnNewMessage(e);
Console.Read();
}

输出如下

CLR VIA C#事件的更多相关文章

  1. CLR 显示实现事件 EventSet内部管理一个字典

    using System; using System.Collections; using System.Collections.Generic; using System.Linq; using S ...

  2. 有关CLR的初学小整理(可能理解不深刻,望大牛指出)

    1. .Net程序通过CLR去加载运行管理代码, 加载CLR的进程成为“宿主”,通常操作系统加载. 加载CLR的进程也可以为某个DLL,也成为“宿主” 2. 宿主接口使宿主能够对运行库的更多方面进行控 ...

  3. NEsper使用的事件类型 z

    NEsper使用的事件类型来描述事件的类型信息.你的应用在启动时可能预先配置定义事件类型,或者在运行时通过API或EPL语法动态的增加事件类型. EPL中的create schema 的语法允许在运行 ...

  4. .NET 中的委托

    1.1.1 定义 委托是一种引用方法的类型.一旦为委托分配了方法,委托将与该方法具有完全相同的行为.委托方法的使用可以像其他任何方法一样,具有参数和返回值,如下面的示例所示: //Code in C# ...

  5. 动手实现一个适用于.NET Core 的诊断工具

    前言 大家可能对诊断工具并不陌生,从大名鼎鼎的 dotTrace,到 .NET CLI 推出的一系列的高效诊断组件(dotnet trace,dotnet sos,dotnet dump)等, 这些工 ...

  6. 《快来为你的 .NET 应用加个监控吧!》更新版本啦

    目录 导读 三种方式处理监控数据 主动推送 ASP.NET Core 自定义URL .NET diagnostics 自定义监控指标 导读 CZGL.ProcessMetrics 是一个 Metric ...

  7. .NET周报【10月第3期 2022-10-25】

    国内文章 聊一聊被 .NET程序员 遗忘的 COM 组件 https://www.cnblogs.com/huangxincheng/p/16799234.html 将Windows编程中经典的COM ...

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

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

  9. CLR via C#深解笔记五 - 事件

    事件处理实际上是一种具有特殊签名的delegate, 像这个样子:public delegate void EventHandler(object sender, EventArgs e);   类型 ...

随机推荐

  1. linux 下find命令 --查找文件名

    1.在某目录下查找名为"elm.cc"的文件 find /home/lijiajia/ -name elm.cc 2.查找文件名中包含某字符(如"elm")的文 ...

  2. uget和aria2

    http://blog.csdn.net/luojiming1990/article/details/9078447 其中的aria2 -v要改成aria2c -v

  3. mysql 导出慢

    转: 导出 mysqldump -uroot -p discuz  -e --max_allowed_packet=1048576 --net_buffer_length=16384 > dis ...

  4. EDIUS中调整YUV曲线的教程

    本篇文章重点地讲解了EDIUS调整YUV曲线的方法,是一篇很详细的EDIUS教程文章,它能帮助新手小伙伴快速掌握EDIUS视频编辑软件的某一知识点.相信坚持学习小编推荐的教程文章,你们会很快入门EDI ...

  5. Python 3 条件、循环和assert、pass、del

    条件: if 条件:     语句块 elif:     语句块 else:     语句块 elif 表示 else if 这居然是合法的!!!1 < x < 2!!! >> ...

  6. Docker实践(3)—浅析device mapper的thin provision

    thin provision是在 kernel3.2 中引入的.它主要有以下一些特点: (1)允许多个虚拟设备存储在相同的数据卷中,从而达到共享数据,节省空间的目的: (2)支持任意深度的快照.之前的 ...

  7. 不使用spring的情况下原生java代码两种方式操作mongodb数据库

    由于更改了mongodb3.0数据库的密码,导致这几天storm组对数据进行处理的时候,一直在报mongodb数据库连接不上的异常.   主要原因实际上是和mongodb本身无关的,因为他们改的是配置 ...

  8. 黄聪:MYSQL使服务器内存CPU占用过高问题的分析及解决方法

    方法一: 使用 show processlist 语句,查找负荷最重的 SQL 语句,优化该SQL,比如适当建立某字段的索引. 方法二: #查看慢SQL日志是否启用mysql> show var ...

  9. mfc_Demo

    内涵图

  10. java 线程的优先级

    //线程的优先级 //线程1 class xc1 implements Runnable{ public void run(){ for(int i=0;i<20;i++){ System.ou ...