Delegates and events in C# are foundational concepts that enable flexible, type-safe method references and event-driven programming. Many developers find them confusing at first, but this guide explains them in a simple, easy-to-understand way.
What is a Delegate?
A delegate is a type-safe object that holds a reference to a method with a specific signature. Delegates are similar to function pointers in C or C++, but they are object-oriented, type-safe, and secure.
Delegates allow you to pass methods as parameters to other methods or assign methods at runtime.
// Define a delegate
public delegate int MathOperation(int x, int y);
// Method matching the delegate signature
public class Calculator
{
public int Add(int a, int b) => a + b;
public int Multiply(int a, int b) => a * b;
}
// Using the delegate
MathOperation operation = new Calculator().Add;
int result = operation(5, 3); // Output: 8
The delegate’s signature (return type + parameters) must match the method it references. This allows delegates to be used as **callbacks** or **pluggable methods** in your code.
Delegate Magic
Delegates are special objects. Unlike normal objects that contain data, a delegate only contains information about a method.
Delegates do not depend on the class of the object they reference; only the method signature matters.
This allows anonymous method invocation and runtime flexibility.
Benefits of Delegates
- Type-safe: Ensures the method signature matches.
- Object-oriented: Fully compatible with OOP principles.
- Secure: No unsafe pointers.
- Flexible: Can be used to pass methods around, define callbacks, and plug in new behavior dynamically.
Types of Delegates
C# delegates come in two main types:
1. Singlecast Delegate
A singlecast delegate points to a single method at a time.
public delegate void Notify(string message);
public class Messenger
{
public void ShowMessage(string msg)
{
Console.WriteLine(msg);
}
}
// Using singlecast delegate
Notify notify = new Messenger().ShowMessage;
notify("Hello World!"); // Only calls ShowMessage
2. Multicast Delegate
A multicast delegate can reference multiple methods. Delegates in C# are multicast by default and derived from System.MulticastDelegate.
public delegate void Notify(string message);
public class Messenger
{
public void ShowMessage(string msg)
{
Console.WriteLine(msg);
}
public void LogMessage(string msg)
{
Console.WriteLine("Log: " + msg);
}
}
Messenger m = new Messenger();
Notify notify = m.ShowMessage;
notify += m.LogMessage; // Add second method
notify("Hello World!");
// Output:
// Hello World!
// Log: Hello World!
Events in C#
An event is a mechanism that allows a class to notify other classes or objects when something happens.
Events are based on delegates and are widely used in GUI programming, data binding, and event-driven applications.
// Declare a delegate for the event
public delegate void ThresholdReachedEventHandler(int threshold);
// Class that publishes the event
public class Counter
{
public event ThresholdReachedEventHandler ThresholdReached;
private int total;
public void Add(int x)
{
total += x;
if (total >= 10)
{
ThresholdReached?.Invoke(total); // Trigger event
}
}
}
// Class that subscribes to the event
public class Listener
{
public void OnThresholdReached(int value)
{
Console.WriteLine($"Threshold reached: {value}");
}
}
// Usage
Counter counter = new Counter();
Listener listener = new Listener();
counter.ThresholdReached += listener.OnThresholdReached;
counter.Add(5);
counter.Add(6); // Triggers event
In this example, the Counter class fires the ThresholdReached event when a certain total is reached,
and the Listener responds to it.
Steps to Define and Use Delegates
- Declare a delegate with a method signature.
- Create methods matching the delegate signature.
- Create a delegate instance and assign methods.
- Invoke the delegate.
- (Optional) Use multicast delegates or events.
Summary Table
| Concept | Definition | Example |
|---|---|---|
| Delegate | Type-safe reference to a method | MathOperation delegate |
| Singlecast Delegate | Points to a single method | Notify notify = messenger.ShowMessage; |
| Multicast Delegate | Points to multiple methods | notify += messenger.LogMessage; |
| Event | Notifies other classes when something happens, based on delegates | ThresholdReached event |
| Anonymous Delegate | Delegate without a named method | notify = delegate(string msg) { Console.WriteLine(msg); }; |
| Callback | Method passed via delegate to be called later | MathOperation used as parameter |