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:
The recommended .NET pattern uses EventHandler<TEventArgs>.
Real-World Scenario: Patient Recovery Notification
Scenario Description
should be notified automatically.
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:
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:
event keyword ensures external classes can only subscribe or unsubscribe
EventHandler<T> provides a standard delegate signature
OnPatientRecovered follows .NET naming guidelines
Null-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.");
}
}
Nurse Subscriber
public class Nurse
{
public void OnPatientRecovered(object sender, PatientRecoveredEventArgs e)
{
Console.WriteLine($"Nurse notified: Patient {e.PatientName} has recovered.");
}
}
Key Point:
Subscribers do not know about each other
They only react to the event
They can be added or removed without changing the publisher
Step 4: Wiring Everything Together
The console application connects the publisher and subscribers.
class Program
{
static void Main(string[] args)
{
var publisher = new PatientRecoveryPublisher();
var doctor = new Doctor();
var nurse = new Nurse();
publisher.PatientRecovered += doctor.OnPatientRecovered;
publisher.PatientRecovered += nurse.OnPatientRecovered;
Console.WriteLine("Enter patient name:");
string patientName = Console.ReadLine();
publisher.TriggerRecovery(patientName);
}
}
What happens internally:
Subscribers register to the event
Publisher raises the event
All subscribers are notified automatically
Console Output
Input:
Enter patient name:
Rahul
Output:
Doctor notified: Patient Rahul has recovered.
Nurse notified: Patient Rahul has recovered.
This confirms that multiple subscribers are notified through a single event
Custom Delegate vs EventHandler<TEventArgs>
1. Using EventHandler<TEventArgs> (Recommended)
Use EventHandler<TEventArgs> when:
Following standard .NET conventions
Event represents a notification
Event data fits into an EventArgs object
Writing maintainable and reusable code
This is the preferred approach for most applications.
2. Using a Custom Delegate
Example:
public delegate void PatientRecoveredHandler(string patientName);
Use a custom delegate when:
Event signature is very specific
You want to avoid EventArgs
Working with legacy systems
Performance-critical scenarios (rare)
Drawbacks of custom delegates:
Recommendation
Prefer EventHandler<TEventArgs> unless you have a strong technical reason not to.
Why This Example Is Educational, Not Production-Level
This example intentionally avoids:
These are important in real applications, but including them would distract from understanding core event concepts.
When Should You Use Events?
Events are suitable for:
Avoid events for:
Conclusion
This article demonstrated how to use events in C# through a simple, real-world example. The hospital patient recovery scenario clearly shows the benefits of the publisher–subscriber pattern and follows .NET best practices using EventHandler<TEventArgs>.
While not production-ready, this example is:
Mastering events is an essential step toward building scalable and maintainable C# applications.
Happy Coding 😊