C# event 和delegate的区别

本文探讨了C#中事件(event)与委托(delegate)的区别,包括调用方式、定义位置及使用场景的不同,并通过示例展示了如何利用委托实现类间的订阅与通知机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

其实说实话 event和delegate 并没有什么特别大的区别,event其实就是特殊化的delegate

1.调用上event只能+=和-=,这样做的意义是为了防止,其余的方法覆盖,但是delegate并没有这种限制,不仅可以+=,-=,还可以直接=一个方法。

2.委托定义的是一个类型,而事件定义的是一个成员

3.event 只能在类内定义,或者接口内定义,而delegate可以在类外类外定义,但不能在接口内,因为接口中只能包含成员

4.event能在接口中定义意味着,我们可以通过接口来获得event,这对于没有引用关系的两个项目来说是十分合适的

委托使用例子(类A订阅类B):

namespace WindowsFormsApplication1
{
    public delegate void SumDelegate(); //定义一个委托类型的SumDelegate

    public class A
    {
    
        public A()
        {
            B b = new B();
            b.sum += method;
        }

        public void method()
        {
            MessageBox.Show("我被调用了");
        }
    }


    public class B
    {
        public SumDelegate sum;   //定义一个委托方法sum
        public void ShowMsg()
        {
            sum();
        }
    }
}






            

转载于:https://www.cnblogs.com/kevinWu7/p/10163526.html

### C# 中 `event` `delegate` 的关系及区别 #### 1. 基本概念 在 C# 中,`delegate` 是一种类型安全的函数指针,用于封装方法的引用。它可以指向静态方法或实例方法,并允许调用这些方法而不必知道它们的具体实现细节[^1]。 而 `event` 则是对 `delegate` 的进一步封装,主要用于发布-订阅模式下的事件处理机制。通过 `event` 关键字定义的成员可以被外部访问,但它仅限于添加 (`+=`) 或移除 (`-=`) 处理程序的操作,无法直接调用底层的 `delegate` 实例[^4]。 --- #### 2. 使用方式对比 ##### (1)Delegate 的基本使用 以下是 `delegate` 的典型定义使用: ```csharp // 定义一个委托类型 public delegate void NotifyEventHandler(object sender, EventArgs e); class Program { static void Main() { // 创建委托实例并绑定方法 NotifyEventHandler handler = new NotifyEventHandler(MethodToInvoke); // 调用委托 handler(null, null); } static void MethodToInvoke(object sender, EventArgs e) { Console.WriteLine("Method invoked!"); } } ``` 上述代码展示了如何定义使用 `delegate` 来封装方法调用逻辑[^2]。 ##### (2)Event 的基本使用 当我们将 `delegate` 封装到 `event` 中时,其主要目的是为了提供更严格的访问控制,防止外部代码直接触发事件。下面是一个简单的例子: ```csharp using System; public class Publisher { // 定义事件 public event Action OnSomethingHappened; public void DoWork() { Console.WriteLine("Doing work..."); OnSomethingHappened?.Invoke(); // 触发事件 } } public class Subscriber { public Subscriber(Publisher publisher) { // 订阅事件 publisher.OnSomethingHappened += HandleEvent; } private void HandleEvent() { Console.WriteLine("Event handled by subscriber."); } } class Program { static void Main() { var publisher = new Publisher(); var subscriber = new Subscriber(publisher); publisher.DoWork(); // 输出: Doing work... Event handled by subscriber. } } ``` 在这个示例中,`OnSomethingHappened` 是基于 `Action` 类型的一个事件。只有 `Publisher` 可以触发它,而其他类可以通过订阅来响应这个事件[^3]。 --- #### 3. 主要区别 | 特性 | Delegate | Event | |---------------------|---------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------| | **本质** | 函数指针,表示一组可执行的方法集合 | 对 `delegate` 的封装,专门用于事件处理 | | **访问权限** | 公开可见,任何地方都可以调用 | 提供受限访问,只能由声明它的类内部触发 | | **适用场景** | 方法回调、多线程通信 | 发布-订阅模型 | | **操作限制** | 支持直接调用 | 不支持直接调用;仅能通过 `+=` 添加处理器或通过 `-=` 移除处理器 | --- #### 4. 使用场景分析 - 如果需要实现跨组件之间的解耦设计(比如 GUI 控件的通知机制),推荐优先考虑 `event`,因为它提供了更好的安全性。 - 当只需要简单地传递方法引用或者构建复杂的回调链表时,则可以直接使用 `delegate`。 --- ### 总结 虽然 `delegate` `event` 都涉及到了方法的动态调用,但两者的设计目标不同:前者侧重灵活性,后者则强调语义上的清晰性安全性。因此,在实际开发过程中应根据具体需求选择合适的工具。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值