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 likeShipOrderinsideOrderService).
你的核心问题:事件会在运行时创建委托实例吗?
Yes—but only when you start subscribing to it. Here’s the flow:
- When the
OrderServiceinstance is created, the internal delegate field (_orderShipped) isnull(no subscribers yet). - When you use
+=to subscribe a handler:
The compiler translates this into a call toorderService.OrderShipped += NotifyCustomer;add_OrderShipped, which creates a new delegate instance (combining the existing_orderShippeddelegate with the newNotifyCustomermethod) and assigns it back to_orderShipped.- Note: Delegates are immutable—every
+=creates a new instance instead of modifying the existing one.
- Note: Delegates are immutable—every
- If you subscribe another handler, the same process repeats: a new delegate instance is created with both methods, replacing the old one.
- When the class triggers the event (e.g.,
OrderShipped?.Invoke(orderId);), it’s actually calling the internal delegate instance (if it’s notnull).
快速示例来巩固
// 委托类型 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

