C#练习——事件
一、任务:利用事件完成热水器温度监控系统设计与实现
实现目标:有一个热水器,包含一个加热器,一个报警器,一个显示器
(1)当水温超过95度时,报警器会开始发出语音,告诉你水的温度
(2)显示器也会改变水温提示,提示水已经烧开了
二、核心架构设计
1. 事件中心 - Heater类(事件发布者)
class Heater
{public event Action<int> myEvnet; // 关键事件:温度变化事件private int value = 0; // 当前水温public void AddHot(){int updateIndex = 0;while (true){if(updateIndex % 9999999 == 0) // 模拟时间间隔{++value;Console.WriteLine("加热到{0}度", value);// 温度达到100度停止加热(测试用)if( value >= 100 ) break;// 温度超过95度触发事件if(value >= 95){if( myEvnet != null ){myEvnet(value); // 触发事件,传递当前温度}// 清空事件订阅(只提示一次)myEvnet = null;}updateIndex = 0;}++updateIndex;}}
}
使用
Action<int>
泛型事件,传递当前温度值空值检查避免空引用异常
事件触发后清空订阅,实现"只提示一次"的逻辑
2. 事件订阅者 - 两个监控系统
Alarm类(报警器)
class Alarm
{public void ShowInfo(int v){Console.WriteLine("当前水温{0}度", v); // 实时报警}
}
Display类(显示器)
class Display
{public void ShowInfo(int v){Console.WriteLine("水开了,当前水温{0}度", v); // 状态显示}
}
三、事件机制深度解析
事件订阅流程
// 主程序中的订阅过程
h.myEvnet += a.ShowInfo; // 报警器订阅
h.myEvnet += d.ShowInfo; // 显示器订阅
事件触发条件
if(value >= 95) // 温度阈值判断
{myEvnet(value); // 触发所有订阅的方法myEvnet = null; // 清空订阅(一次性通知)
}
四、完整代码
using System;namespace Lesson13_练习题
{class Heater{public event Action<int> myEvnet;private int value = 0;public void AddHot(){int updateIndex = 0;while (true){if(updateIndex % 9999999 == 0){++value;Console.WriteLine("加热到{0}度", value);//为了不频繁打印 超过100度 直接 不加热 测试用if( value >= 100 ){break;}//温度超过95度 就触发 报警器和显示器显示信息if(value >= 95){if( myEvnet != null ){myEvnet(value);}//如果只想提示一次 这清空事件容器即可myEvnet = null;}//隔一段时间 加一点温度updateIndex = 0;}++updateIndex;}}}class Alarm{public void ShowInfo(int v){Console.WriteLine("当前水温{0}度", v);}}class Display{public void ShowInfo(int v){Console.WriteLine("水开了,当前水温{0}度", v);}}#endregionclass Program{static void Main(string[] args){Console.WriteLine("事件练习题");Heater h = new Heater();Alarm a = new Alarm();Display d = new Display();h.myEvnet += a.ShowInfo;h.myEvnet += d.ShowInfo;//加热h.AddHot();}}
}