1. 为什么需要委托与事件?
在C#开发中,我们经常遇到这样的场景:当某个对象的状态发生变化时,需要通知其他对象做出响应。比如用户点击按钮时触发一系列操作,或者传感器数据更新时需要刷新UI显示。传统的方式是通过直接调用方法来实现,但这种紧耦合的设计会带来诸多问题。
委托(delegate)本质上是一种类型安全的函数指针,它允许我们将方法作为参数传递。想象一下餐厅的点餐场景:顾客(调用方)不需要知道厨房(被调用方)具体如何做菜,只需要把订单(委托)交给服务员即可。这种间接调用的方式解耦了对象之间的关系。
事件(event)则是建立在委托基础上的更高级抽象,它遵循发布-订阅模式。就像杂志订阅服务:出版社(事件发布者)不需要知道具体有哪些订阅者,只需要在出新刊时发出通知;订阅者(事件处理程序)可以自由地注册或取消关注。
重要提示:委托和事件是C#实现观察者模式的核心机制,也是框架设计中回调逻辑的基础设施。WPF/WinForms的控件事件、ASP.NET的页面生命周期事件都基于此实现。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 委托的完整使用指南
2.1 委托的定义与使用
委托声明需要指定方法签名,这与接口定义类似。假设我们需要处理温度报警:
csharp复制// 声明委托类型
public delegate void TemperatureAlertHandler(float temperature);
// 符合签名的方法
public void LogHighTemperature(float temp)
{
Console.WriteLine($"警报!当前温度:{temp}℃");
}
// 使用委托
TemperatureAlertHandler alert = LogHighTemperature;
alert(38.5f); // 触发委托调用
委托支持多播(multicast),即一个委托实例可以关联多个方法。通过+=运算符可以添加方法调用链:
csharp复制alert += temp => Console.WriteLine($"已通知值班人员"); // 添加Lambda表达式
alert += new AirConditioner().TurnOnCooling; // 添加对象方法
alert(40.0f); // 会依次调用所有注册方法
2.2 内置泛型委托
.NET框架提供了三种常用泛型委托,避免重复定义:
-
Action:无返回值的方法委托
csharp复制Action<string> print = Console.WriteLine; print("Hello Action"); -
Func:带返回值的方法委托
csharp复制Func<int, int, int> add = (x, y) => x + y;
