一个例子学习事件与委托

事件是对象发送的消息,以发信号通知操作的发生。操作可能是由用户交互(例如鼠标单击)引起的,也可能是由某些其他的程序逻辑触发的。引发事件的对象称为事件发送方。捕获事件并对其作出响应的对象叫做事件接收方。在事件通信中,事件发送方类不知道哪个对象或方法将接收到它引发的事件。所需要的是在源和接收方之间存在一个媒介(或类似指针的机制)。

 

委托是可保存对方法的引用的类。与其他的类不同的是委托类具有一个签名,并且它只能对与其签名匹配的方法进行引用。这样,委托就等效于一个类型安全的函数指针或一个回调。虽然委托具有许多其他的用途,但以下例子中只使用了它的事件处理功能。

<think>好的,用户现在想要一个用C#实现事件委托例子。之前他们问过关于NXOpen库实现加厚操作的问题,现在突然转向C#的基础概念,可能是因为他们在学习过程中遇到了新的需求,或者需要将事件委托应用到之前的项目中。 首先,我需要确定用户对事件委托的理解程度。他们可能已经了解了一些面向对象编程的基础,但需要具体的例子来巩固这些概念。考虑到他们之前的问题是关于NX二次开发,可能他们现在在学习C#,或者需要在NX Open的C#脚本中使用事件委托。 接下来,我需要构建一个简单明了的例子,涵盖委托的定义、事件的声明、触发和订阅。例子要贴近实际应用,比如用户界面中的按钮点击,或者更通用的场景,比如状态变化通知。这里可能选择温度监控的例子,因为它直观且容易理解。 然后,要确保代码结构清晰,步骤明确。需要分步骤解释委托事件、发布者和订阅者的关系。同时,要说明事件委托的基本用法,比如定义委托类型、声明事件、订阅事件和处理方法。还要注意事件的命名习惯,比如使用EventHandler后缀和EventArgs作为参数。 另外,用户可能有疑问的地方需要提前预判。例如,为什么使用EventHandler<TEventArgs>而不是自定义委托?这时候可能需要解释.NET框架中的约定和最佳实践。或者,如何处理多个订阅者,事件触发的顺序等。但为了保持例子简洁,可能先不涉及太复杂的内容,而是专注于基础实现。 还要考虑用户可能在实际应用中遇到的问题,比如事件未订阅导致的空引用异常,因此代码中应该包含空检查。另外,使用弱引用或取消订阅的问题可能也是需要注意的,但在基础例子中可能暂时不深入,避免信息过载。 最后,总结部分需要强调事件委托在解耦和模块化中的作用,以及它们在实际应用中的常见用途,比如UI交互、异步编程等。同时,提供进一步学习的资源或建议,比如官方文档或进阶主题,帮助用户继续深入学习。</think>好的!以下是一个使用C#实现**事件(Event)和委托(Delegate)**的简单示例,通过模拟一个“温度监控系统”来演示它们的用法。 --- ### **示例场景** - **目标**:当温度传感器检测到温度超过阈值时,触发事件并通知所有订阅者(如报警器、日志记录器)。 - **步骤**: 1. 定义委托类型。 2. 声明事件。 3. 实现事件的发布者(温度传感器)。 4. 实现事件的订阅者(报警器、日志记录器)。 5. 订阅事件并触发。 --- ### **完整代码示例** ```csharp using System; // 1. 定义事件参数(传递温度数据) public class TemperatureChangedEventArgs : EventArgs { public double CurrentTemperature { get; } public DateTime Timestamp { get; } public TemperatureChangedEventArgs(double temp) { CurrentTemperature = temp; Timestamp = DateTime.Now; } } // 2. 定义发布者(温度传感器) public class TemperatureSensor { // 3. 声明事件(基于泛型委托EventHandler<T>) public event EventHandler<TemperatureChangedEventArgs> TemperatureExceeded; private double _threshold; public TemperatureSensor(double threshold) { _threshold = threshold; } // 4. 模拟温度检测 public void CheckTemperature(double currentTemp) { if (currentTemp > _threshold) { // 触发事件 OnTemperatureExceeded(new TemperatureChangedEventArgs(currentTemp)); } } // 5. 触发事件的方法(遵循命名规范 OnXXX) protected virtual void OnTemperatureExceeded(TemperatureChangedEventArgs e) { TemperatureExceeded?.Invoke(this, e); // 安全调用(避免空引用) } } // 6. 定义订阅者(报警器) public class Alarm { public void Alert(object sender, TemperatureChangedEventArgs e) { Console.WriteLine($"🚨 警报!温度过高:{e.CurrentTemperature}°C(时间:{e.Timestamp})"); } } // 7. 定义订阅者(日志记录器) public class Logger { public void LogTemperature(object sender, TemperatureChangedEventArgs e) { Console.WriteLine($"📝 日志记录:温度 {e.CurrentTemperature}°C 已超过阈值"); } } class Program { static void Main() { // 8. 创建对象 var sensor = new TemperatureSensor(threshold: 30); var alarm = new Alarm(); var logger = new Logger(); // 9. 订阅事件 sensor.TemperatureExceeded += alarm.Alert; sensor.TemperatureExceeded += logger.LogTemperature; // 10. 模拟温度变化 sensor.CheckTemperature(25); // 不触发事件 sensor.CheckTemperature(35); // 触发事件 } } ``` --- ### **输出结果** ``` 📝 日志记录:温度 35°C 已超过阈值 🚨 警报!温度过高:35°C(时间:2023-10-01 14:30:00) ``` --- ### **核心概念解释** 1. **委托(Delegate)** - 本质是“函数指针”,定义方法的签名(参数和返回类型)。 - 示例中直接使用.NET内置的`EventHandler<T>`委托,无需自定义。 2. **事件(Event)** - 基于委托的封装,提供安全的订阅/取消订阅机制。 - 发布者(`TemperatureSensor`)通过事件通知订阅者。 3. **事件参数(EventArgs)** - 通过继承`EventArgs`传递数据(如温度值和时间戳)。 4. **订阅触发** - 使用`+=`订阅事件,`-=`取消订阅。 - 通过`Invoke`触发事件(需检查`null`)。 --- ### **实际应用场景** - **UI开发**:按钮点击事件(`Button.Click`)。 - **异步编程**:后台任务完成通知。 - **游戏开发**:角色血量变化触发UI更新。 --- ### **进阶技巧** - **取消订阅**:使用`-=`移除事件处理。 - **线程安全**:多线程中触发事件时,需检查委托是否为`null`的副本。 - **弱事件**:避免内存泄漏(如使用`WeakEventManager`)。 --- 如果需要对代码进一步扩展(如动态添加订阅者或自定义委托),可以随时告诉我!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

abeniaj0427

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值