|
1 | 1 | ---
|
2 | 2 | title: Delegates vs. events
|
3 | 3 | description: Learn the difference between delegates and events and when to use each of these features of .NET Core.
|
4 |
| -ms.date: 06/20/2016 |
| 4 | +ms.date: 03/11/2025 |
5 | 5 | ms.subservice: fundamentals
|
6 |
| -ms.assetid: 0fdc8629-2fdb-4a7c-a433-5b9d04eaf911 |
7 | 6 | ---
|
8 |
| - |
9 | 7 | # Distinguishing Delegates and Events
|
10 | 8 |
|
11 | 9 | [Previous](modern-events.md)
|
12 | 10 |
|
13 |
| -Developers that are new to the .NET Core platform often struggle |
14 |
| -when deciding between a design based on `delegates` and a design |
15 |
| -based on `events`. The choice of delegates or events is often difficult, because the two |
16 |
| -language features are similar. Events are even built using |
17 |
| -the language support for delegates. |
| 11 | +Developers that are new to the .NET platform often struggle when deciding between a design based on `delegates` and a design based on `events`. The choice of delegates or events is often difficult, because the two language features are similar. Events are even built using the language support for delegates. An event handler declaration declares a delegate type. |
18 | 12 |
|
19 |
| -They both offer a late binding scenario: they enable scenarios |
20 |
| -where a component communicates by calling a method that is only |
21 |
| -known at run time. They both support single and multiple subscriber |
22 |
| -methods. You may find this referred to as singlecast and multicast |
23 |
| -support. They both support similar syntax for adding and removing |
24 |
| -handlers. Finally, raising an event and calling a delegate use exactly the same method call syntax. They even both support the same `Invoke()` |
25 |
| -method syntax for use with the `?.` operator. |
| 13 | +Both offer a late binding scenario: they enable scenarios where a component communicates by calling a method that is only known at run time. They both support single and multiple subscriber methods. You might find these terms referred to as single cast and multicast support. They both support similar syntax for adding and removing handlers. Finally, raising an event and calling a delegate use exactly the same method call syntax. They even both support the same `Invoke()` method syntax for use with the `?.` operator. |
26 | 14 |
|
27 |
| -With all those similarities, it is easy to have trouble determining when |
28 |
| -to use which. |
| 15 | +With all those similarities, it's easy to have trouble determining when to use which. |
29 | 16 |
|
30 | 17 | ## Listening to Events is Optional
|
31 | 18 |
|
32 |
| -The most important consideration in determining which language feature |
33 |
| -to use is whether or not there must be an attached subscriber. If your |
34 |
| -code must call the code supplied by the subscriber, you should |
35 |
| -use a design based on delegates when you need to implement callback. If your code can complete all its |
36 |
| -work without calling any subscribers, you should use a |
37 |
| -design based on events. |
38 |
| - |
39 |
| -Consider the examples built during this section. The code you built |
40 |
| -using `List.Sort()` must be given a comparer function in order to |
41 |
| -properly sort the elements. LINQ queries must be supplied with delegates |
42 |
| -in order to determine what elements to return. Both used a design built |
43 |
| -with delegates. |
44 |
| - |
45 |
| -Consider the `Progress` event. It reports progress on a task. |
46 |
| -The task continues to proceed whether or not there are any listeners. |
47 |
| -The `FileSearcher` is another example. It would still search and find |
48 |
| -all the files that were sought, even with no event subscribers attached. |
49 |
| -UX controls still work correctly, even when there are no subscribers |
50 |
| -listening to the events. They both use designs based on events. |
| 19 | +The most important consideration in determining which language feature to use is whether or not there must be an attached subscriber. If your code must call the code supplied by the subscriber, you should use a design based on delegates when you need to implement callback. If your code can complete all its work without calling any subscribers, you should use a design based on events. |
| 20 | + |
| 21 | +Consider the examples built during this section. The code you built using `List.Sort()` must be given a comparer function in order to properly sort the elements. LINQ queries must be supplied with delegates in order to determine what elements to return. Both used a design built with delegates. |
| 22 | + |
| 23 | +Consider the `Progress` event. It reports progress on a task. The task continues to proceed whether or not there are any listeners. The `FileSearcher` is another example. It would still search and find all the files that were sought, even with no event subscribers attached. UX controls still work correctly, even when there are no subscribers listening to the events. They both use designs based on events. |
51 | 24 |
|
52 | 25 | ## Return Values Require Delegates
|
53 | 26 |
|
54 |
| -Another consideration is the method prototype you would want for your |
55 |
| -delegate method. As you've seen, the delegates used for events all |
56 |
| -have a void return type. You've also seen that there are idioms to |
57 |
| -create event handlers that do pass information back to event sources |
58 |
| -through modifying properties of the event argument object. While these |
59 |
| -idioms do work, they are not as natural as returning a value from a |
60 |
| -method. |
| 27 | +Another consideration is the method prototype you would want for your delegate method. As you saw, the delegates used for events all have a void return type. There are idioms to create event handlers that do pass information back to event sources through modifying properties of the event argument object. While these idioms do work, they aren't as natural as returning a value from a method. |
61 | 28 |
|
62 |
| -Notice that these two heuristics may often both be present: If your |
63 |
| -delegate method returns a value, it will likely impact the algorithm |
64 |
| -in some way. |
| 29 | +Notice that these two heuristics can often both be present: If your delegate method returns a value, it affects the algorithm in some way. |
65 | 30 |
|
66 | 31 | ## Events Have Private Invocation
|
67 | 32 |
|
68 |
| -Classes other than the one in which an event is contained can only add |
69 |
| -and remove event listeners; only the class containing the event can |
70 |
| -invoke the event. Events are typically public class members. |
71 |
| -By comparison, delegates are often passed as parameters and stored as |
72 |
| -private class members, if they are stored at all. |
| 33 | +Classes other than the one in which an event is contained can only add and remove event listeners; only the class containing the event can invoke the event. Events are typically public class members. By comparison, delegates are often passed as parameters and stored as private class members, if they're stored at all. |
73 | 34 |
|
74 | 35 | ## Event Listeners Often Have Longer Lifetimes
|
75 | 36 |
|
76 |
| -That event listeners have longer lifetimes is a slightly weaker justification. However, you may find that event-based designs are more natural when the event source will be |
77 |
| -raising events over a long period of time. You can see examples of |
78 |
| -event-based design for UX controls on many systems. Once you subscribe to an event, |
79 |
| -the event source may raise events throughout the lifetime of the program. |
80 |
| -(You can unsubscribe from events when you no longer need them.) |
| 37 | +The longer lifetime of event listeners is a slightly weaker justification. However, you might find that event-based designs are more natural when the event source is raising events over a long period of time. You can see examples of event-based design for UX controls on many systems. Once you subscribe to an event, the event source can raise events throughout the lifetime of the program. (You can unsubscribe from events when you no longer need them.) |
81 | 38 |
|
82 |
| -Contrast that with many delegate-based designs, where a delegate is |
83 |
| -used as an argument to a method, and the delegate is not used after that |
84 |
| -method returns. |
| 39 | +Contrast that with many delegate-based designs, where a delegate is used as an argument to a method, and the delegate isn't used after that method returns. |
85 | 40 |
|
86 | 41 | ## Evaluate Carefully
|
87 | 42 |
|
88 |
| -The above considerations are not hard and fast rules. Instead, they |
89 |
| -represent guidance that can help you decide which choice is best for |
90 |
| -your particular usage. Because they are similar, you can even |
91 |
| -prototype both, and consider which would be more natural to work |
92 |
| -with. They both handle late binding scenarios well. Use the one |
93 |
| -that communicates your design the best. |
| 43 | +The above considerations aren't hard and fast rules. Instead, they represent guidance that can help you decide which choice is best for your particular usage. Because they're similar, you can even prototype both, and consider which would be more natural to work with. They both handle late binding scenarios well. Use the one that communicates your design the best. |
0 commit comments