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

C#中事件与关联委托的关系:是否会创建委托实例?

事件与委托的关系:你需要理清的核心区别

Great question—this is one of the most common "aha!" moments when learning C# events and delegates, so you’re totally on the right track by digging into this. Let’s break this down clearly:

首先:委托是一个「方法签名类型」

Think of a delegate like a blueprint that defines what a method must look like (return type, parameters). For example:

public delegate void OrderShippedHandler(int orderId);

This is a type—just like int or List<string>. You can create instances of this type, attach methods that match its signature, and invoke those methods through the delegate instance.

事件是委托实例的「受控封装器」

An event is not a delegate instance itself—it’s a wrapper around a delegate instance that restricts what external code can do with it. When you declare an event using a delegate type:

public class OrderService
{
    // 事件基于委托类型声明
    public event OrderShippedHandler OrderShipped;
}

Under the hood, the compiler generates a private delegate field (let’s call it _orderShipped) and two public methods: add_OrderShipped and remove_OrderShipped (which map to the += and -= operators you use).

关键限制:

  • External code can’t directly assign to the event (e.g., orderService.OrderShipped = MyMethod; is invalid—you can only use += or -=). This prevents external code from wiping out existing subscribers.
  • External code can’t invoke the event directly (e.g., orderService.OrderShipped(123); is invalid). Only the class that declared the event can trigger it (usually via a method like ShipOrder inside OrderService).

你的核心问题:事件会在运行时创建委托实例吗?

Yes—but only when you start subscribing to it. Here’s the flow:

  1. When the OrderService instance is created, the internal delegate field (_orderShipped) is null (no subscribers yet).
  2. When you use += to subscribe a handler:
    orderService.OrderShipped += NotifyCustomer;
    
    The compiler translates this into a call to add_OrderShipped, which creates a new delegate instance (combining the existing _orderShipped delegate with the new NotifyCustomer method) and assigns it back to _orderShipped.
    • Note: Delegates are immutable—every += creates a new instance instead of modifying the existing one.
  3. If you subscribe another handler, the same process repeats: a new delegate instance is created with both methods, replacing the old one.
  4. When the class triggers the event (e.g., OrderShipped?.Invoke(orderId);), it’s actually calling the internal delegate instance (if it’s not null).

快速示例来巩固

// 委托类型
public delegate void OrderShippedHandler(int orderId);

public class OrderService
{
    public event OrderShippedHandler OrderShipped;

    public void ShipOrder(int orderId)
    {
        // 内部触发事件
        OrderShipped?.Invoke(orderId);
    }
}

// 使用代码
var orderService = new OrderService();
// 第一次订阅:创建第一个委托实例
orderService.OrderShipped += (id) => Console.WriteLine($"Order {id} shipped!");
// 第二次订阅:创建新的委托实例,包含两个方法
orderService.OrderShipped += (id) => Console.WriteLine($"Sending email for order {id}");

orderService.ShipOrder(456);
// 输出:
// Order 456 shipped!
// Sending email for order 456

To sum up:

  • Delegates are the type that defines the method signature.
  • Events are controlled wrappers around delegate instances, enforcing encapsulation (only subscribe/unsubscribe externally, trigger internally).
  • The underlying delegate instance is created (and updated) dynamically as you subscribe handlers at runtime.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:02:47