Events
An event lets an object announce that something happened, without knowing who is listening. Follow an Oven that declares public event Action? Done: two handler methods subscribe with +=, Bake raises the event with Done?.Invoke() and every handler runs in order, one handler leaves with -=, and the compiler stops outside code from raising the event itself. The program prints Beep!, Flash!, Flash!.
5 quick questions
Pick an answer to see why. Your score saves with your progress.
01Beep and Flash subscribe to oven.Done in that order. What happens when the oven raises Done?
Done holds a multicast delegate. Invoking it calls each method in its invocation list, one after another, in the order they were added with +=.
02Why does Bake write Done?.Invoke() and not just Done.Invoke()?
A field-like event with no subscribers holds null. The null-conditional operator ?. only calls Invoke when Done is not null.
03Code outside class Oven writes oven.Done(); . What happens?
That is what the event keyword adds to a plain delegate field: other code may subscribe and unsubscribe, but only the class that declares the event can raise it or replace it.
04After oven.Done += Beep; oven.Done += Flash; oven.Done -= Beep; what does the invocation list hold?
-= removes the matching handler (Beep). Only Flash is left, so the next Bake prints Flash! once.
05What does public event Action? Done; declare?
Action is a delegate type for void methods with no parameters, so Beep and Flash fit. The ? marks that the event may be null when nobody has subscribed.
Glossary
- Event
- A member that lets an object (or class) tell other code that something happened. Declared with the event keyword and a delegate type.
- Publisher
- The object that declares and raises the event; here, the oven.
- Subscriber / event handler
- A method that is added to an event and runs when the event is raised; here, Beep and Flash.
- Subscribe (+=) and unsubscribe (-=)
- Add a handler to an event's invocation list, or remove it. The only things code outside the class can do with an event.
- Raise
- Call the event's handlers, from inside the declaring class, usually with Done?.Invoke().
- Invocation list
- The ordered list of methods a (multicast) delegate calls when it is invoked.
- Multicast delegate
- One delegate object whose invocation list holds more than one method; += combines delegates into one.
- Action
- A ready-made .NET delegate type for methods that take no parameters and return nothing (void).
Notes and sources
- The program is real C# for .NET 8 or later. Put the whole file in Program.cs and dotnet run prints Beep!, Flash!, Flash!, one per line.
- Delegates never change. Each += makes a new delegate with a longer invocation list (Delegate.Combine) and stores it in the event; each -= makes a new, shorter one (Delegate.Remove). The figure shows the list being edited in place.
- A field-like event such as Done is really a hidden delegate field plus add and remove accessors that the compiler writes; += and -= outside the class call those accessors.
- Most .NET events follow a standard pattern: the type EventHandler or EventHandler<TEventArgs>, and handlers with two parameters, sender (who raised it) and e (the event data). Action is used here to keep the example short.
- Handlers run one after another on the thread that raised the event. If one handler throws an exception, the handlers after it are not called.
- Microsoft Learn: Events (C# programming guide)
- Microsoft Learn: Introduction to events
- Microsoft Learn: The event keyword
- Microsoft Learn: How to subscribe to and unsubscribe from events
- Microsoft Learn: How to combine delegates (multicast delegates)
- Microsoft Learn: Delegate.Remove method
- Microsoft Learn: Member access operators, including ?.
- Microsoft Learn: Compiler error CS0070
- Microsoft Learn: Standard .NET event patterns
- Microsoft Learn: Handling and raising events (.NET)
Quiz Unlocks after the last step.