委托与事件的基本区别
委托(Delegate)是类型安全的函数指针,允许将方法作为参数传递或存储。事件(Event)是基于委托的封装,提供更安全的发布-订阅模式。
委托示例代码:
csharp
public delegate void MyDelegate(string message);
public class DelegateExample
{
public static void DisplayMessage(string msg)
{
Console.WriteLine($"委托调用: {msg}");
}
public static void Main()
{
MyDelegate del = DisplayMessage;
del("直接调用委托");
}
}
事件示例代码:
csharp
public class EventPublisher
{
public event MyDelegate MessageEvent;
public void TriggerEvent(string msg)
{
MessageEvent?.Invoke(msg);
}
}
public class EventSubscriber
{
public void OnMessageReceived(string msg)
{
Console.WriteLine($"事件触发: {msg}");
}
}
public static void Main()
{
var publisher = new EventPublisher();
var subscriber = new EventSubscriber();
publisher.MessageEvent += subscriber.OnMessageReceived;
publisher.TriggerEvent("测试事件");
}
关键差异分析
-
封装性
- 委托可直接通过
=赋值或Invoke调用 - 事件仅允许类内部触发(
+=/-=操作符)
- 委托可直接通过
-
使用场景
- 委托适用于回调机制和异步编程
- 事件适用于观察者模式,如UI控件交互
-
线程安全
事件默认包含线程安全调用:
csharpMessageEvent?.Invoke(msg);等效于:
csharpvar handler = MessageEvent; if (handler != null) handler(msg);
设计选择建议
- 需要外部触发操作时使用委托
- 需要限制外部触发权限时使用事件
- 事件本质上是通过
add/remove访问器封装的委托
语法对比
| 特性 | 委托 | 事件 |
|---|---|---|
| 声明方式 | public delegate void X |
public event X Y |
| 外部调用 | 允许直接调用 | 仅允许+=/-= |
| 空值检查 | 需手动检查 | 自动生成线程安全调用 |