C# Event

Introduction
Hello all, today I back with another C# topic, and today I will share what i learned about C# Event. I hope with this article you will know more about C# Event and use it on your project.
What It Is?
In C#, an event is a specialized form of delegate. Unlike delegates, which allow methods from outside the class to be assigned using both = and += operators, an event restricts assignments to only using the += operator. Additionally, events can only be raised within the class where they are declared, ensuring that they are raised only in controlled circumstances.
Why Implement It?
There are several pros and cons to consider before implement an event in our project. Here are some of them:
Pros
Enhance the clarity of the code flow.
Minimize dependencies on other classes.
Preventing direct invocation of a delegate from outside its declaring class reduces the risk of unintended side effects.
Cons
It may be challenging for new programmers to understand.
Could potentially cause performance overhead if there's too many method assign to it.
Could potentially cause memory leaks If the event are not properly unsubscribed.
How It Works?
To understand how event work in the system, let's implement it first. To implement an event, all you need to do is add an event keyword in front of the delegate, there are two different types of delegate that can be used for an event:
Regular Delegates e.g.
public event [delegate/Action/Func/Predicate] OnOpenButtonPressed;Event Handler Delegates e.g.
public event EventHandler CloseButtonPressEventHandler;
The implementation of these events is as shown in the code below:
using System;
namespace Lncodes.Example.Event;
public abstract class UIController
{
public event Action OnOpenButtonPressed;
public event EventHandler CloseButtonPressEventHandler;
}
In the code above, I have created events using the Action delegate and the EventHandler delegate. These events are designed to be triggered whenever the open or close button is pressed. After implementing these events in the code, here's what will happen in the system:
When a delegate is declared as an event, the system ensures that the event can only be raised within the class that declares it. Additionally, methods can only be assigned to the event using the
+=operator.Assigning and raising an event is similar to working with a delegate. When you assign a method to an event, it references that method. Raising the event will then also invoke all methods that have been added to it.
Console Application
In my console application, an event is used to display a message when a button is pressed. This console application uses three different types of delegates: Action (a general delegate without arguments), EventHandler (a specialized delegate without specific arguments), and EventHandler<T> (a specialized delegate with specific arguments).
Below is a list of the classes I used to create this console application, along with a brief explanation of each class:
| Class | Description |
UIController | This class is used as a parent class that manages general UI-related operations for all menu classes. |
MainMenuUIController | This class is used to manage UI-related operations for the main menu. |
ResultMenuUIController | This class is used to manage UI-related operations for the results menu. |
CloseButtonEventArgs | This class is used to store event data that is passed through an EventHandler. |
Program | This class is used to display button pressed events messages on the console. |
In the video above, the console application displays a message when the button is pressed. There are three different buttons, each representing a different type of delegate used to handle events. Below is a list of all the delegate types used in this console application, along with a brief explanation of each delegate:
| Delegate Types | Description |
event Action | This delegate is used to handle the event that is raised when the open button is pressed. The output can be seen in the console message no 1. |
event EventHandler | This delegate is used to handle the event that is raised when the animate button is pressed. The output can be seen in the console message no 2. |
event EventHandler<String> | This delegate is used to handle the event that is raised when the close button is pressed. The output can be seen in the console message no 3. |
By implementing events, managing and handling button actions becomes significantly more efficient. Additionally, using different delegate types for various events can further enhance action management. Each delegate type is designed to ensure that events are handled appropriately, leading to a more organized and effective event-handling process.
Additional Information
I have discovered some additional information about C# Event. If you have any additional information about C# Event that you'd like to share, please feel free to leave a comment.
Naming Guidelines
When implementing events, following specific naming guidelines can help ensure code readability and consistency. Here are some naming conventions recommended by Microsoft:
Do use a verb or verb phrase when naming an event e.g., opening, closed, etc.
Do use verb-ing for event names that are raised before an operation is performed e.g., opening, closing, etc.
Do use verb-ed for event names that are raised after an operation is performed e.g., opened, closed, etc.
Do use 'On' prefix for the regular delegate event names, e.g.
public event Action OnOpenButtonPressed;.Do use 'EventHandler' suffix for event handler delegate event names e.g.
public event EventHandler CloseButtonPressEventHandler;.Do use the 'EventArgs' suffix for class or struct names that are intended to be used as arguments for
EventHandlere.g.public class CloseButtonEventArgs { }.Do use the 'On' prefix for method names that raise an
EventHandlere.g.protected void OnOpenButtonPressed().
Regular Delegate VS Event Handler Delegate
Both regular delegates and event handler delegates have similar functionality to managing method references within an event-driven architecture. Due to these similarities, choosing between them can be challenging. Here are some key factors to consider before making a decision:
When using
EventHandler, there are two default parameters:senderandeventArgs. In contrast, regular delegates do not include these default parameters.Use
EventHandlerwhen it’s important to know which object raised the event. For instance, in an inheritance architecture,EventHandlerhelps determine which child class is raising the event, thanks to its defaultsenderparameter which provides the instance of the object that raised the event.
public event Func<int, object, EventArgs> OpenButtonEventHandler.Event VS Delegate
Both events and delegates have similar functionality to manage method references and provide a way to register methods. Due to these similarities, choosing between them can be challenging. Here are some key factors to consider before making a decision:
An event is typically used to notify the subscribing classes when something occurs in the publisher class, while a delegate is typically used for callbacks or to pass methods as parameters.
An event can only be raised within the class where it’s declared, while a delegate can be invoked from outside its declaring class. This restriction helps ensure that the event’s handling remains encapsulated within the class that declares it.
Outside its class declaration, an event can only be modified by adding or removing event handlers using the
+=and-=operators. In comparison, a delegate can be can be assigned or modified using=,+,-,+=, and-=operators.
Further Discoveries
Here are some further discoveries I have gathered from various sources that may provide a deeper understanding of C# Event:
When using
EventHandlerand no additional arguments are needed, it's recommended to useEventArgs.Emptyinstead ofnull. This maintains consistency and prevents null reference errors at runtime.When using a static
EventHandler, it's acceptable to passnullfor thesenderargument. However, for non-staticEventHandlerinstances, avoid passingnullas thesenderargument.When using the
EventHandlerdelegate for an event, it’s essential to define a method to raise the event, and this method should be marked asprotected virtual. This allows subclasses to override the method and raise the event, which is essential for properly implementing event handling in an inheritance-based architecture.When an
EventHandlerthat returns values is required, a customEventHandlercan be defined using a regular delegate, likepublic event Func<int, object, EventArgs> CloseButtonPressEventHandler.Since C# 2.0, the generic
EventHandler<T>can be used to define the type of argument for anEventHandler. This approach is recommended when theEventHandlerneeds to pass an argument, as it eliminates the need to cast theEventArgsparameter to access the argument value.





