C#委托与事件机制的实战解析
C#委托允许将方法作为参数传递或存储,结合事件机制可实现松耦合的代码设计。本文通过分析“热水器烧水”这一经典场景,演示如何声明委托、触发事件以及处理回调。
实现目标
我们需要构建一个简单的系统:当热水器的水温达到特定阈值(95度以上)时,自动触发警报器和显示器的提示功能。这展示了事件驱动编程的核心逻辑。
第1步:声明委托与事件类结构
using System;
namespace Delegate {
public class Heater {
private int temperature;
// 1. 声明委托类型,定义回调方法的签名
public delegate void BoilHandler(int param);
// 2. 基于委托声明事件
public event BoilHandler BoilEvent;
// ... 后续逻辑见下文
using System;
namespace Delegate {
public class Heater {
private int temperature;
// 1. 声明委托类型,定义回调方法的签名
public delegate void BoilHandler(int param);
// 2. 基于委托声明事件
public event BoilHandler BoilEvent;
// ... 后续逻辑见下文
在 Heater 类中,首先使用 delegate 关键字定义了 BoilHandler 委托,规定其接收一个整型参数并返回空。随后,利用 event 关键字将该委托包装为事件,以防止外部直接赋值覆盖所有监听者。
第2步:实现核心触发逻辑
public class Heater {
// ... 属性与方法定义
public void BoilWater() {
for (int i = 0; i <= 100; i++) {
temperature = i;
// 判断条件:温度超过95度
if (temperature > 95) {
// 安全性检查:确保有注册的方法
if (BoilEvent != null) {
BoilEvent(temperature); // 调用所有注册的回调方法
}
}
}
}
}
public class Heater {
// ... 属性与方法定义
public void BoilWater() {
for (int i = 0; i <= 100; i++) {
temperature = i;
// 判断条件:温度超过95度
if (temperature > 95) {
// 安全性检查:确保有注册的方法
if (BoilEvent != null) {
BoilEvent(temperature); // 调用所有注册的回调方法
}
}
}
}
}
BoilWater 方法模拟了加温过程。当循环检测到温度大于95时,检查 BoilEvent 是否为空,若不空则传入当前温度值执行。注意:实际项目中应关注线程安全问题(如 BoilEvent?.Invoke(temperature)),但在基础示例中使用此写法足以说明原理。
第3步:定义响应方法
我们需要两个不同的类来实现具体的业务逻辑,以展示事件的多态处理能力:
public class Alarm {
public void MakeAlert(int param) {
Console.WriteLine("Alarm:嘀嘀嘀,水已经 {0} 度了:",param);
}
}
public class Display {
// 静态方法同样可以被委托指向
public static void ShowMsg(int param) {
Console.WriteLine("Display:水快烧开了,当前温度:{0}度。",param);
}
}
Alarm 提供了实例方法,而 Display 提供了静态方法。这证明委托可以绑定到不同类型的成员函数上。
第4步:程序入口与事件订阅
class Program {
static void Main() {
Heater heater = new Heater();
Alarm alarm = new Alarm();
// 订阅方式1:使用现有对象实例
heater.BoilEvent += alarm.MakeAlert;
// 订阅方式2:使用匿名对象
heater.BoilEvent += (new Alarm()).MakeAlert;
// 订阅方式3:注册静态方法
heater.BoilEvent += Display.ShowMsg;
// 开始运行,观察输出结果
heater.BoilWater();
}
}
class Program {
static void Main() {
Heater heater = new Heater();
Alarm alarm = new Alarm();
// 订阅方式1:使用现有对象实例
heater.BoilEvent += alarm.MakeAlert;
// 订阅方式2:使用匿名对象
heater.BoilEvent += (new Alarm()).MakeAlert;
// 订阅方式3:注册静态方法
heater.BoilEvent += Display.ShowMsg;
// 开始运行,观察输出结果
heater.BoilWater();
}
}
在 Main 方法中,我们通过 += 运算符完成了事件的注册(订阅)。本例采用了多播委托(Multicast Delegate),即一个事件可以同时挂载多个处理方法。
运行结果分析
编译并运行上述代码后,控制台将输出以下信息:
Alarm:嘀嘀嘀,水已经 96 度了: Alarm:嘀嘀嘀,水已经 96 度了: Display:水快烧开了,当前温度:96度。
由于使用了循环递增且在96度时触发了三次注册逻辑(实际上是连续三个单位温度都满足>95且进入了回调阶段),我们看到了三条输出。第一条来自实例化的 alarm,第二条来自临时的匿名 Alarm 对象,第三条来自静态的 Display。这验证了委托能够正确地将参数传递给各个已注册的观察者。
总结
以上就是C#委托现实示例分析的详细内容,更多关于C#委托用法设计的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













