You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C#中何时使用Event而非Delegate?示例与场景解析

问题背景

我有如下两个示例类:

void Main()
{
    Provider1 myProvider1 = new Provider1();
    myProvider1.MyEvent += (sender, eventData) => Console.WriteLine($"the event1 handled : {eventData.Data}");

    myProvider1.DoSth();

    //
    Provider2 myProvider2 = new Provider2();
    myProvider2.MyEvent = (sender, eventData) => Console.WriteLine($"the event2 handled : {eventData.Data}");

    myProvider2.DoSth();
}

public class SampleEventArgs : EventArgs
{
    public string Data { get; }
    public SampleEventArgs(string data)
    {
        Data = data;
    }
}

public class Provider1
{
    public event EventHandler<SampleEventArgs> MyEvent;

    public void DoSth()
    {
        MyEvent?.Invoke(this, new SampleEventArgs("TestData"));
    }
}

public class Provider2
{
    public Action<object, SampleEventArgs> MyEvent;
    public void DoSth()
    {
        MyEvent?.Invoke(this, new SampleEventArgs("TestData"));
    }
}

其中Provider1使用event定义MyEvent,Provider2使用Action<object, SampleEventArgs>类型的委托模拟event功能,两者实现效果一致,想了解各自的适用场景及原因(已知Action是一种Delegate)。


适用场景分析

一、event关键字实现(Provider1)的适用场景

  • 遵循.NET标准事件模式的场景:比如UI控件事件、数据变更通知、框架级事件等。event是CLR专门为事件机制设计的语法糖,严格遵循sender + EventArgs的标准模式,其他开发者一看就能理解这是一个事件,符合.NET开发的通用约定,降低协作成本。
  • 需要封装性和安全性的场景:event的访问权限被限制——外部代码只能通过+=添加订阅、-=移除订阅,无法直接调用Invoke触发事件,也不能用=直接覆盖所有订阅。这能避免外部恶意触发事件,或者误操作覆盖已有订阅逻辑,保证类内部的事件触发逻辑完全由类自身控制。
  • 多订阅者的场景:如果一个事件需要绑定多个处理逻辑(比如一个按钮点击同时触发日志记录、UI更新、数据提交),event会自动维护委托链,多个订阅者的逻辑会依次执行,不会被覆盖,这种场景下用event是最优选择。

二、公开Action委托实现(Provider2)的适用场景

  • 轻量单回调场景:如果只需要一个回调逻辑(比如某个异步任务完成后仅通知一个处理方法),用Action更简洁,不需要遵循严格的事件模式,代码更轻量化。
  • 需要动态替换回调的场景:如果业务逻辑中需要频繁切换处理逻辑(比如根据不同的业务场景替换通知后的处理行为),直接给Action赋值新的委托比-=移除旧订阅再+=添加新订阅更直接高效。
  • 非标准回调场景:当不需要遵循sender + EventArgs模式,或者回调参数更灵活时,Action可以自定义参数类型(示例中用了和事件一致的参数,但实际可更灵活),适合一些自定义的、非框架级的简单回调需求。

内容的提问来源于stack exchange,提问作者TheMah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 14:25:36