事件和委托: 第 6 页 .Net Framework中的委托与事件
原文发布时间为:2008-11-01 —— 来源于本人的百度文章 [由搬家工具导入]
.Net Framework中的委托与事件
尽管上面的范例很好地完成了我们想要完成的工作,但是我们不仅疑惑:为什么.Net Framework 中的事件模型和上面的不同?为什么有很多的EventArgs参数?
在回答上面的问题之前,我们先搞懂 .Net Framework的编码规范:
- 委托类型的名称都应该以EventHandler结束。
- 委托的原型定义:有一个void返回值,并接受两个输入参数:一个Object 类型,一个 EventArgs类型(或继承自EventArgs)。
- 事件的命名为 委托去掉 EventHandler之后剩余的部分。
- 继承自EventArgs的类型应该以EventArgs结尾。
再做一下说明:
- 委托声明原型中的Object类型的参数代表了Subject,也就是监视对象,在本例中是 Heater(热水器)。回调函数(比如Alarm的MakeAlert)可以通过它访问触发事件的对象(Heater)。
- EventArgs 对象包含了Observer所感兴趣的数据,在本例中是temperature。
上面这些其实不仅仅是为了编码规范而已,这样也使得程序有更大的灵活性。比如说,如果我们不光想获得热水器的温度,还想在Observer端(警报器或者显示器)方法中获得它的生产日期、型号、价格,那么委托和方法的声明都会变得很麻烦,而如果我们将热水器的引用传给警报器的方法,就可以在方法中直接访问热水器了。
现在我们改写之前的范例,让它符合 .Net Framework 的规范:
输出为:
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度。
// 省略 ...
using System;
using System.Collections.Generic;
using System.Text;
namespace Delegate {
// 热水器
public class Heater {
private int temperature;
public string type = "RealFire 001"; // 添加型号作为演示
public string area = "China Xian"; // 添加产地作为演示
//声明委托
public delegate void BoiledEventHandler(Object sender, BoliedEventArgs e);
public event BoiledEventHandler Boiled; //声明事件
// 定义BoliedEventArgs类,传递给Observer所感兴趣的信息
public class BoliedEventArgs : EventArgs {
public readonly int temperature;
public BoliedEventArgs(int temperature) {
this.temperature = temperature;
}
}
// 可以供继承自 Heater 的类重写,以便继承类拒绝其他对象对它的监视
protected virtual void OnBolied(BoliedEventArgs e) {
if (Boiled != null) { // 如果有对象注册
Boiled(this, e); // 调用所有注册对象的方法
}
}
// 烧水。
public void BoilWater() {
for (int i = 0; i <= 100; i++) {
temperature = i;
if (temperature > 95) {
//建立BoliedEventArgs 对象。
BoliedEventArgs e = new BoliedEventArgs(temperature);
OnBolied(e); // 调用 OnBolied方法
}
}
}
}
// 警报器
public class Alarm {
public void MakeAlert(Object sender, Heater.BoliedEventArgs e) {
Heater heater = (Heater)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, Heater.BoliedEventArgs e) { //静态方法
Heater heater = (Heater)sender;
Console.WriteLine("Display:{0} - {1}: ", heater.area, heater.type);
Console.WriteLine("Display:水快烧开了,当前温度:{0}度。", e.temperature);
Console.WriteLine();
}
}
class Program {
static void Main() {
Heater heater = new Heater();
Alarm alarm = new Alarm();
heater.Boiled += alarm.MakeAlert; //注册方法
heater.Boiled += (new Alarm()).MakeAlert; //给匿名对象注册方法
heater.Boiled += new Heater.BoiledEventHandler(alarm.MakeAlert); //也可以这么注册
heater.Boiled += Display.ShowMsg; //注册静态方法
heater.BoilWater(); //烧水,会自动调用注册过对象的方法
}
}
}
事件和委托: 第 6 页 .Net Framework中的委托与事件的更多相关文章
- Unity C# 多态 委托 事件 匿名委托 Lambda表达式 观察者模式 .NET 框架中的委托和事件
一.多态 里氏替换原则: 任何能用基类的地方,可以用子类代替,反过来不行.子类能够在基类的基础上增加新的行为.面向对象设计的基本原则之一. 开放封闭原则: 对扩展开放,意味着有新的需求或变化时,可以对 ...
- 观察者模式与.Net Framework中的委托与事件
本文文字内容均选自<大话设计模式>一书. 解释:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够 ...
- C# 中的委托和事件
觉得这篇文章写的非常好,大神之作,由简入繁,对我这种初学者来说帮忙很大,特此留存下. 摘自:http://tracefact.net/CSharp-Programming/Delegates-and- ...
- C# 中的委托和事件(转)
引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去 ...
- C# 中的委托和事件(转载)
引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去 ...
- 【转】C# 中的委托和事件
阅读目录 C# 中的委托和事件 引言 将方法作为方法的参数 将方法绑定到委托 事件的由来 事件和委托的编译代码 委托.事件与Observer设计模式 .Net Framework中的委托与事件 总结 ...
- c#中的委托和事件(转)
引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去 ...
- C#中的委托、事件和设计模式(转载)
引言 委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人 ...
- 转载 -- C# 中的委托和事件
原文地址:http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-in-CSharp.aspx C# 中的委托和事件 引言 委 ...
随机推荐
- Android基础夯实--重温动画(二)之Frame Animation
心灵鸡汤:天下事有难易乎,为之,则难者亦易矣:不为,则易者亦难矣. 摘要 当你已经掌握了Tween Animation之后,再来看Frame Animation,你就会顿悟,喔,原来Frame Ani ...
- PL/SQL学习笔记(三)
-----创建一个序列,再创建一个表(主键是数字),通过序列生成该表的主键值. create table mytb1( m_id number primary key, m_name ) not nu ...
- vue项目中常用的一些公共方法
//校验手机号码 export function isSpecialPhone(num) { return /^1[2,3,4,5,7,8]\d{9}$/.test(num) } //校验中英文姓名 ...
- 51nod 1067 Bash游戏 V2
基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 有一堆石子共有N个.A B两个人轮流拿,A先拿.每次只能拿1,3,4颗,拿到最后1颗石子的人获胜.假设A B都非常聪 ...
- os x 中出现message sent to deallocated instance 的错误总结
一般是程序中的某一个对象被release 了两次 一般情况下是与你定义的类型有关 这里面我的错误是吧 NSString 类型的变量的属性 设置为了 assign 了 目测与这个有关 补充object- ...
- SQLite - SELECT查询
SQLite - SELECT查询 SQLite SELECT语句用于获取数据从一个SQLite数据库表返回数据结果表的形式.也称为result-sets这些结果表. 语法 SQLite SELECT ...
- oracle的Hint
与优化器模式相关的Hint 1 ALl_ROWS 让优化器启用CBO /*+ all_rows */ 2 first_rows(n) 让优化器启用CBO 模式,而且得到目标sql的执行计 ...
- Microsoft Project 2010基础使用方法
5.1 项目管理与Microsoft Project2010 Microsoft Project2010深受广大项目管理工程师的青睐. 5.1.1 项目管理的概念 项目管理是项目管理者在有限的资源约束 ...
- vue :class 可以接收 字符串 数组 和 对象 对象里面的key值 根据true或false 显示不显示
vue :class 可以接收 字符串 数组 和 对象 对象里面的key值 根据true或false 显示不显示 https://cn.vuejs.org/v2/guide/class-and-sty ...
- 小程序request请求 POST请求参数传递不到后台
wx.request({ url: 'https://xxx.com/xxxx.php', data: { 'jscode': code }, method: 'POST', header: { &q ...