.NET Framework通过委托提供了一种回调函数机制。

internal delegate void FeedBack(Int32 value);

内部委托FeedBack的声明,一个委托要指定一个回调方法的签名,在本例中,FeedBack委托标识了一个方法,该方法获取一个参数(int32类型),并返回void。

其实.NET的委托类似于C语言的函数指针,区别在于.NET委托是类型安全的。

使用委托的四部曲:

(1)定义一种委托类型

(2)委托执行时要调用方法

(3)定义一个委托实例

(4)委托实例的调用

委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。

使用委托可以将多个方法绑定到同一个委托变量,当调用此变量时(这里用“调用”这个词,是因为此变量代表一个方法),可以依次调用所有绑定的方法。

事件其实没什么不好理解的,声明一个事件不过类似于声明一个进行了封装的委托类型的变量而已。

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, BoiledEventArgs e);
public event BoiledEventHandler Boiled; //声明事件 // 定义BoiledEventArgs类,传递给Observer所感兴趣的信息
public class BoiledEventArgs : EventArgs {
public readonly int temperature;
public BoiledEventArgs(int temperature) {
this.temperature = temperature;
}
} // 可以供继承自 Heater 的类重写,以便继承类拒绝其他对象对它的监视
protected virtual void OnBoiled(BoiledEventArgs e) {
if (Boiled != null) { // 如果有对象注册
Boiled(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, Heater.BoiledEventArgs 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.BoiledEventArgs 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(); //烧水,会自动调用注册过对象的方法
}
}
} 输出为:
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度。
// 省略 ...

  

浅探委托(delegate)和事件(event)的更多相关文章

  1. 重温委托(delegate)和事件(event)

    1.delegate是什么 某种意义上来讲,你可以把delegate理解成C语言中的函数指针,它允许你传递一个类A的方法m给另一个类B的对象,使得类B的对象能够调用这个方法m,说白了就是可以把方法当作 ...

  2. 关于C# 委托(delegate)与事件(event)的用法及事例

    C#中的委托和事件对于新手可能会有一点难理解,所以先从一个小例子入手,以便能更好的理解其如何使用.有一个学生每天定闹钟在早上6点起床,所以当每天早上6点的时候,闹钟就会响起来,从而学生才会按时起床. ...

  3. C#中的委托(Delegate)和事件(Event)

    原文地址:C#中的委托(Delegate)和事件(Event) 作者:jiyuan51 把C#中的委托(Delegate)和事件(Event)放到现在讲是有目的的:给下次写的设计模式--观察者(Obs ...

  4. (转)C#中的委托(Delegate)和事件(Event)

    转自:http://blog.chinaunix.net/uid-576762-id-2733751.html   把C#中的委托(Delegate)和事件(Event)放到现在讲是有目的的:给下次写 ...

  5. 【温故知新】c#事件event

    从上一篇文章[温故知新]C#委托delegate可知,委托delegate和事件Event非常的相似,区别就是event关键字,给delegate穿上了个“马甲”. 让我们来看官方定义: 类或对象可以 ...

  6. 并发编程概述 委托(delegate) 事件(event) .net core 2.0 event bus 一个简单的基于内存事件总线实现 .net core 基于NPOI 的excel导出类,支持自定义导出哪些字段 基于Ace Admin 的菜单栏实现 第五节:SignalR大杂烩(与MVC融合、全局的几个配置、跨域的应用、C/S程序充当Client和Server)

    并发编程概述   前言 说实话,在我软件开发的头两年几乎不考虑并发编程,请求与响应把业务逻辑尽快完成一个星期的任务能两天完成绝不拖三天(剩下时间各种浪),根本不会考虑性能问题(能接受范围内).但随着工 ...

  7. C#:委托(delegate)和事件(event) (转)

    委托(delegate): 它是C#语言里面的函数指针,代表可以指向某一个函数,在运行的时候调用这个函数的实现.下面来看看它的实现步骤: 声明一个delegate对象. 实现和delegate具有相同 ...

  8. C# Note2:委托(delegate) & Lambda表达式 & 事件(event)

    前言 本文主要讲述委托和Lambda表达式的基础知识,以及如何通过Lambda表达式实现委托调用,并阐述.NET如何将委托用作实现事件的方式. 参考:C#高级编程 1.什么是委托(delegate)? ...

  9. 【Unity|C#】基础篇(8)——委托(Delegate)/ 事件(Event)

    [学习资料] <C#图解教程>(第13~14章):https://www.cnblogs.com/moonache/p/7687551.html 电子书下载:https://pan.bai ...

随机推荐

  1. linux下解压命令大全

    .tar 解包:tar xvf FileName.tar打包:tar cvf FileName.tar DirName(注:tar是打包,不是压缩!)———————————————.gz解压1:gun ...

  2. nginx配置图片防盗链

    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)${ expires 30d; access_log off; valid_referers none blocked ...

  3. 捕获EF提交异常

    try { } catch (DbEntityValidationException dbex) { string errMsg = string.Empty; foreach (var eve in ...

  4. chain.doFilter(request,response)含义

    过滤器的生命周期一般都要经过下面三个阶段: 初始化 当容器第一次加载该过滤器时,init() 方法将被调用.该类在这个方法中包含了一个指向 Filter Config 对象的引用.我们的过滤器实际上并 ...

  5. sqlserver权限体系(下)

    简介 在上一篇文章中,我对主体的概念做了全面的阐述.本篇文章接着讲述主体所作用的安全对象以及所对应的权限. 理解安全对象(Securable) 安全对象,是SQL Server 数据库引擎授权系统控制 ...

  6. phpStudy 创建多个站点,绑定域名

    默认情况下,phpStudy 的站点根目录是在它自己的WWW目录,比如 F:\phpStudy\WWW,访问的地址可以是 http://127.0.0.1/   或 http://localhost/ ...

  7. oracle 的wm_concat函数使用

    转载自:http://blog.itpub.net/post/42245/522757 首先让我们来看看这个神奇的函数wm_concat(列名),该函数可以把列值以","号分隔起来 ...

  8. 关于帧中继和ppp的补充笔记

    帧中继: · 两个设备都要启用 帧中继功能, 否则是不能 ping通的 · 两个设备上的接口serial要 no shutdown · · 一定要配置dlci地址(号). 否则就不能起来pvc 可以 ...

  9. linux网络:常用命令(二)

    1.ping命令:与Windows下基本功能一样但也有所区别 1.命令格式: ping [选项] ip地址或域名主机等 选项 -c 加次数 -d 使用Socket的SO_DEBUG功能. -f 极限检 ...

  10. SQL笔记 - CTE递归实例(续):显示指定部门的全称

    前一篇文章中已经可以取得所有部门的全称,但现在又有个新的需求: 只想得到某一个部门的部门全称,虽然可以用where条件来过滤,但是会有点小浪费. 这时我们可以从后往前找,先看下效果: 最后一条就是,行 ...