# C# Event

## Introduction

Hello all, today I back with another [C#](https://www.lncodes.com/series/csharp) 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.

<div data-node-type="callout">
<div data-node-type="callout-emoji">⚠</div>
<div data-node-type="callout-text">Before diving deeper into C# Event, it’s recommended to first read my C# Delegate post at <a target="_blank" rel="noopener noreferrer nofollow" href="https://lncodes.com/csharp-delegate" style="pointer-events: none">C# Delegate - Last Night Codes</a>.</div>
</div>

## 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:

1. Regular Delegates e.g. `public event [delegate/Action/Func/Predicate] OnOpenButtonPressed;`
    
2. Event Handler Delegates e.g. `public event EventHandler CloseButtonPressEventHandler;`
    

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">To learn more about the differences between regular delegates and event handler delegates, see the section on Regular Delegates vs. Event Handler Delegates below.</div>
</div>

The implementation of these events is as shown in the code below:

```csharp
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:

1. 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.
    
2. 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. |

%[https://youtu.be/8m9U541UXoA] 

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.

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">The source code for this console application can be viewed and downloaded at <a target="_blank" rel="noopener nofollow" class="text-editor-link" href="https://github.com/lncodes/csharp-event" style="pointer-events: none">Project Repository – Github</a>.</div>
</div>

## 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 `EventHandler` e.g. `public class CloseButtonEventArgs { }`.
    
* Do use the 'On' prefix for method names that raise an `EventHandler` e.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: `sender` and `eventArgs`. In contrast, regular delegates do not include these default parameters.
    
* Use `EventHandler` when it’s important to know which object raised the event. For instance, in an inheritance architecture, `EventHandler` helps determine which child class is raising the event, thanks to its default `sender` parameter which provides the instance of the object that raised the event.
    

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">In my opinion, any delegate with two arguments (the sender and the event data) can be considered as an event handler delegate type, even if it's declared using a regular delegate e.g. <code>public event Func&lt;int, object, EventArgs&gt; OpenButtonEventHandler</code>.</div>
</div>

### 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.
    

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">To learn more about C# Delegate, check out my post at <a target="_blank" rel="noopener" class="text-editor-link" href="https://lncodes.com/csharp-delegate" style="pointer-events: none">C# Delegate - Last Night Codes</a>.</div>
</div>

### Further Discoveries

Here are some further discoveries I have gathered from various sources that may provide a deeper understanding of C# Event:

* When using `EventHandler` and no additional arguments are needed, it's recommended to use `EventArgs.Empty` instead of `null`. This maintains consistency and prevents null reference errors at runtime.
    
* When using a static `EventHandler`, it's acceptable to pass `null` for the `sender` argument. However, for non-static `EventHandler` instances, avoid passing `null` as the `sender` argument.
    
* When using the `EventHandler` delegate for an event, it’s essential to define a method to raise the event, and this method should be marked as `protected 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 `EventHandler` that returns values is required, a custom `EventHandler` can be defined using a regular delegate, like `public event Func<int, object, EventArgs> CloseButtonPressEventHandler`.
    
* Since C# 2.0, the generic `EventHandler<T>` can be used to define the type of argument for an `EventHandler`. This approach is recommended when the `EventHandler` needs to pass an argument, as it eliminates the need to cast the `EventArgs` parameter to access the argument value.
    

## Reference

1. [C# Event – Microsoft](https://docs.microsoft.com/en-us/dotnet/standard/events/)
    
2. [C# Event Handler – Microsoft](https://docs.microsoft.com/en-us/dotnet/api/system.eventhandler)
    
3. [C# Event Design Guidelines – Microsoft](https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/event)
    
4. [C# Event Naming Guidelines – Microsoft](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-type-members#names-of-events)
