#region// 定义BoiledEventArgs类,传递给Observer所感兴趣的信息public class BoiledEventArgs : EventArgs{public readonly int temperature;public BoiledEventArgs(int temperature){this.temperature = temperature;}}//热水器public class Heared {public string type = "RealFire 001";       // 添加型号作为演示public string area = "China Xian";         // 添加产地作为演示private int temperature;public delegate void BoidHandler(Object sender, BoiledEventArgs e); //声明委托public event BoidHandler BoidEvent;  //声明事件// 可以供继承自 Heared的类重写,以便继承类拒绝其他对象对它的监视protected virtual void OnBoiled(BoiledEventArgs e){if (BoidEvent != null){ // 如果有对象注册BoidEvent(this, e);  // 调用所有注册对象的方法
            }}//烧水public void BoilWater() {for (int i = 0; i < 100; i++){temperature = i;if (temperature>95){//建立BoiledEventArgs 对象。BoiledEventArgs e = new BoiledEventArgs(temperature);OnBoiled(e);  // 调用 OnBolied方法
                }}}}// 警报器public class Alarm{public void MakeAlert(Object sender, BoiledEventArgs e){Heared heater = (Heared)sender;     //这里是不是很熟悉呢?//访问 sender 中的公共字段Console.WriteLine("Alarm:{0} - {1}: ", heater.area, heater.type);Console.WriteLine("Alarm: 嘀嘀嘀,水已经 {0} 度了:", e.temperature);Console.WriteLine();}}// 显示器public class Display{public static void ShowMsg(Object sender,BoiledEventArgs e){   //静态方法Heared heater = (Heared)sender;Console.WriteLine("Display:{0} - {1}: ", heater.area, heater.type);Console.WriteLine("Display:水快烧开了,当前温度:{0}度。", e.temperature);Console.WriteLine();}}class Program{static void Main(){Heared heater = new Heared();Alarm alarm = new Alarm();heater.BoidEvent += alarm.MakeAlert;   //注册方法heater.BoidEvent += (new Alarm()).MakeAlert;      //给匿名对象注册方法heater.BoidEvent += new Heared.BoidHandler(alarm.MakeAlert);    //也可以这么注册heater.BoidEvent += Display.ShowMsg;       //注册静态方法
heater.BoilWater();   //烧水,会自动调用注册过对象的方法
        }}
#endregion

输出为:
Alarm:China Xian - RealFire 001:
Alarm: 嘀嘀嘀,水已经 96 度了:
Alarm:China Xian - RealFire 001:
Alarm: 嘀嘀嘀,水已经 96 度了:
Alarm:China Xian - RealFire 001:
Alarm: 嘀嘀嘀,水已经 96 度了:
Display:China Xian - RealFire 001:
Display:水快烧开了,当前温度:96度。
// 省略 ...

Observer设计模式中主要包括如下两类对象:

  1. Subject:监视对象,它往往包含着其他对象所感兴趣的内容。在本范例中,热水器就是一个监视对象,它包含的其他对象所感兴趣的内容,就是temprature字段,当这个字段的值快到100时,会不断把数据发给监视它的对象。
  2. Observer:监视者,它监视Subject,当Subject中的某件事发生的时候,会告知Observer,而Observer则会采取相应的行动。在本范例中,Observer有警报器和显示器,它们采取的行动分别是发出警报和显示水温。

在本例中,事情发生的顺序应该是这样的:

  1. 警报器和显示器告诉热水器,它对它的温度比较感兴趣(注册)。
  2. 热水器知道后保留对警报器和显示器的引用。
  3. 热水器进行烧水这一动作,当水温超过95度时,通过对警报器和显示器的引用,自动调用警报器的MakeAlert()方法、显示器的ShowMsg()方法。

类似这样的例子是很多的,GOF对它进行了抽象,称为Observer设计模式:Observer设计模式是为了定义对象间的一种一对多的依赖关系,以便于当一个对象的状态改变时,其他依赖于它的对象会被自动告知并更新。Observer模式是一种松耦合的设计模式

.Net Framework的编码规范:

  • 委托类型的名称都应该以EventHandler结束。
  • 委托的原型定义:有一个void返回值,并接受两个输入参数:一个Object 类型,一个 EventArgs类型(或继承自EventArgs)。
  • 事件的命名为 委托去掉 EventHandler之后剩余的部分。
  • 继承自EventArgs的类型应该以EventArgs结尾。

再做一下说明:

  1. 委托声明原型中的Object类型的参数代表了Subject,也就是监视对象,在本例中是 Heated(热水器)。回调函数(比如Alarm的MakeAlert)可以通过它访问触发事件的对象(Heated)。
  2. EventArgs 对象包含了Observer所感兴趣的数据,在本例中是temperature。

转载于:https://www.cnblogs.com/mancomeon/p/4688685.html

C#关于事件的几个好例子相关推荐

  1. 委托与事件_从有趣的例子出发去解析

    曾经自以为掌握了委托与事件的关系及区别,然而看起来并没有.其实有很多知识,只是我们觉得自己掌握了,但是事实上我们真正的掌握了吗? 本文会从有趣的比喻出发来理解委托与事件的关系: 首先,先把官方的概念贴 ...

  2. JS 监听 键盘按键 事件 以Enter键为例子

    实现的功能是  用手按键盘Enter键 达到点击 js的button确定按钮同样的效果 其中js主要代码如下,写在<script></script>里面. keyCode==1 ...

  3. 在C#中使用代理的方式触发事件

    事件(event)是一个非常重要的概念,我们的程序时刻都在触发和接收着各种事件:鼠标点击事件,键盘事件,以及处理操作系统的各种事件.所谓事件就是由某个对象发出的消息.比如用户按下了某个按钮,某个文件发 ...

  4. WMI Series :事件预订和处理

    WMI事件概述 对于从事Winows编程的开发人员来说,事件驱动的应用程序设计是再熟悉不过了,但是WMI中的事件又是一个什么样的概念呢?对于宝贵的内存和CPU资源,管理员需要不断的监视其性能:对于磁盘 ...

  5. boost log 能不能循环覆盖_前端基础进阶(十四):深入核心,详解事件循环机制...

    Event Loop JavaScript的学习零散而庞杂,很多时候我们学到了一些东西,但是却没办法感受到进步!甚至过了不久,就把学到的东西给忘了.为了解决自己的这个困扰,在学习的过程中,我一直在试图 ...

  6. jQuery绑定事件的三种常见方式(bind、one、【change、click、keydown、hover】)

    一.bind(type,[data],fn):为每个匹配元素的特定事件绑定对应的事件处理函数. 也可以同时给一个元素绑定多个事件,我们来看一下例子: <!DOCTYPE html> < ...

  7. JavaScript 事件冒泡简介及应用(转)

    http://www.jb51.net/article/21801.htm 一.什么是事件冒泡 在一个对象上触发某类事件(比如单击onclick事件),如果此对象定义了此事件的处理程序,那么此事件就会 ...

  8. 看懂 ,学会 .NET 事件的正确姿势

    一.事件的本质        举个例子你是个取向正常的青年男性,有个身材火辣,年轻貌美,腿长肤白的美女,冲你一笑,给你讲了一个ABCD羊吃草的故事.你有什么反应? 可能你关注点在于颜值,身材,故事,故 ...

  9. Spring5源码解析-Spring中的异步事件

    上一篇 Spring框架中的事件和监听器并未对Spring框架中的异步事件涉及太多,所以本篇是对其一个补充. 同步事件有一个主要缺点:它们在所调用线程的本地执行(也就是将所调用线程看成主线程的话,就是 ...

最新文章

  1. ios手机怎么连接adb命令_手机蓝牙怎么连接汽车蓝牙放音乐,车载蓝牙播放器怎么用...
  2. 国内最牛逼的笔记,不接受反驳!!
  3. Android Resources
  4. ML之NN:利用神经网络的BP算法解决XOR类(异或非)问题(BP solve XOR Problem)
  5. csv文件用excel打开有多行是空的,用sublime打开空白行没有''处理方案
  6. mybatis插入图片处理--mysql
  7. mybatis mapper配置 bigint_Mybatis-plus 入门
  8. 路由器中继模式WISP、Client + AP、AP模式的区别和适使用场景
  9. influxdb java api使用_Influxdb入门使用
  10. 吉林大学高级程序设计(红皮书例题)(1~7章)
  11. paypal 国际版网站集成
  12. Ant Design 省市区联动数据
  13. 解决 Ubuntu 安装显卡驱动后,屏幕变黄的原因
  14. VMware NAT 模式配置端口映射
  15. 米洛个人修炼术:如何倍增你的功力修行速度达成健康体魄
  16. 虹软1:N 基于mysql的插件udf 人脸比较速度优化。。。。
  17. 十分钟时间搞懂怎么用JS代码渲染实时时间
  18. 什么是LL(1)、LR(0)、LR(1)文法、LR分析表—编译原理
  19. jsp管理系统页面模板_基于ssm的人事管理系统
  20. 爬虫:查看Chrome版本

热门文章

  1. python能做高频交易吗_python金融高频交易Python ord()是什么?ord()有什么用?
  2. Java实现excel的读与写(Apache POI)
  3. Matlab | 空间域水印技术:LSB(Least Significant Bit):计算峰值信噪比PSNR(matlab源代码)
  4. activemq mysql集群配置_ActiveMQ专题--集群,高可用方案
  5. pd 生成mysql 脚本_PowerDesigner 如何生成数据库更新脚本
  6. python3随笔-梯度下降法
  7. 【机器学习】总结机器学习3个时代的算力规律:大模型的出现改变了什么?
  8. 【NLP】EMNLP'21 | 让压缩语言模型自动搜索最优结构!
  9. Bengio团队因果学习论文反思:为何机器学习仍在因果关系中挣扎?
  10. 【数据分析】数据分析基础:SQL重要知识点梳理!