Introduction
In C#, events provide a structured way for one component to notify other components when something important happens. They are a core part of building loosely coupled and extensible systems, and are widely used in UI frameworks, backend services, and enterprise applications.
This article explains how events work in C# using a simple, real-world example. The goal is to help beginners and intermediate developers understand the concepts, structure, and best practices behind events.
Note:
This article is written purely for educational purposes. The example focuses on clarity and learning, not on production-level concerns such as threading, logging, error handling, or performance optimization.
What Is an Event in C#?
An event is a mechanism that allows a class (the publisher) to notify one or more other classes (the subscribers) when a specific action occurs.
Key characteristics of events:
Support publisher–subscriber pattern
Allow multiple subscribers
Promote loose coupling
Are built on delegates
The recommended .NET pattern uses EventHandler<TEventArgs>.
Real-World Scenario: Patient Recovery Notification
Scenario Description
A hospital system tracks patient recovery.
When a patient recovers:
A Doctor
A Nurse
should be notified automatically.
The hospital system should not be tightly coupled with doctors or nurses.
This is a natural fit for events.
Step 1: Creating a Custom EventArgs Class
In .NET, event data should be passed using a class that derives from EventArgs.
public class PatientRecoveredEventArgs : EventArgs
{
public string PatientName { get; set; }
}Why this is needed:
Keeps event data strongly typed
Follows .NET conventions
Allows future extension without breaking subscribers
Step 2: Creating the Publisher Class
The publisher defines and raises the event.
public class PatientRecoveryPublisher
{
public event EventHandler<PatientRecoveredEventArgs> PatientRecovered;
protected virtual void OnPatientRecovered(string patientName)
{
PatientRecovered?.Invoke(this, new PatientRecoveredEventArgs
{
PatientName = patientName
});
}
public void TriggerRecovery(string patientName)
{
OnPatientRecovered(patientName);
}
}Explanation:
eventkeyword ensures external classes can only subscribe or unsubscribeEventHandler<T>provides a standard delegate signatureOnPatientRecoveredfollows .NET naming guidelinesNull-conditional invocation prevents runtime exceptions
Step 3: Creating Subscriber Classes
Subscribers react to the event by providing methods that match the delegate signature.
Doctor Subscriber
public class Doctor
{
public void OnPatientRecovered(object sender, PatientRecoveredEventArgs e)
{
Console.WriteLine($"Doctor notified: Patient {e.PatientName} has recovered.");
}
}
Join the conversation! Your thoughts help the community grow.