Delegates and Events in C#: Complete Beginner's Guide
Delegates and Events are core features of C# that enable communication between different parts of an application. They are commonly used in desktop applications, web applications, game development, and event-driven systems.
Understanding delegates and events helps developers write flexible, reusable, and loosely coupled code. In this guide, you'll learn how delegates work, how events are built on top of delegates, and how both are used in real-world applications.
- What Are Delegates?
- Why Delegates Are Useful
- Creating Custom Delegates
- Using Delegates
- Action, Func, and Predicate
- What Are Events?
- Creating Events
- Event Handlers
- Real-World Examples
- Best Practices
What Is a Delegate?
A delegate is a type that stores references to methods. It allows one method to be passed to another method as a parameter.
You can think of a delegate as a function pointer that is type-safe and object-oriented.
Why Use Delegates?
- Create flexible code.
- Support callback methods.
- Enable event-driven programming.
- Reduce tight coupling between classes.
- Improve code reusability.
Creating a Custom Delegate
public delegate void MessageDelegate(string message);
The delegate above can reference any method that accepts a string parameter and returns void.
Using a Delegate
public class Program
{
public static void ShowMessage(string text)
{
Console.WriteLine(text);
}
public static void Main()
{
MessageDelegate messageDelegate =
ShowMessage;
messageDelegate("Hello World");
}
}
The delegate stores a reference to the ShowMessage method and executes it when invoked.
Delegates as Method Parameters
public static void ExecuteAction(
MessageDelegate action)
{
action("Delegate Executed");
}
ExecuteAction(ShowMessage);
Passing delegates as parameters allows methods to execute different behaviors without changing their implementation.
Multicast Delegates
Delegates can reference multiple methods simultaneously.
public static void FirstMessage(string text)
{
Console.WriteLine("First: " + text);
}
public static void SecondMessage(string text)
{
Console.WriteLine("Second: " + text);
}
MessageDelegate handler =
FirstMessage;
handler += SecondMessage;
handler("Hello");
Both methods will execute when the delegate is invoked.
Built-In Delegate: Action
Action is a built-in delegate that returns void.
Action<string> display =
message =>
{
Console.WriteLine(message);
};
display("Using Action");
Built-In Delegate: Func
Func returns a value.
Func<int, int, int> add =
(a, b) => a + b;
int result = add(5, 10);
Built-In Delegate: Predicate
Predicate returns a Boolean value.
Predicate<int> isEven =
number => number % 2 == 0;
bool result = isEven(4);
What Is an Event?
An event is a mechanism that allows a class to notify other classes when something happens.
Events are built on top of delegates and provide a safer way to implement notifications.
Creating an Event
public class OrderService
{
public event Action? OrderPlaced;
public void PlaceOrder()
{
Console.WriteLine("Order Created");
OrderPlaced?.Invoke();
}
}
Subscribing to an Event
var service = new OrderService();
service.OrderPlaced += () =>
{
Console.WriteLine(
"Email Notification Sent");
};
service.PlaceOrder();
When PlaceOrder executes, all subscribed event handlers are automatically called.
Real-World Event Examples
- Button click events.
- User registration notifications.
- Email sending systems.
- Order processing workflows.
- Game state updates.
- Background service notifications.
Delegates vs Events
| Delegate | Event |
|---|---|
| Can be invoked directly. | Can only be invoked by the declaring class. |
| Represents a method reference. | Represents notifications. |
| Used for callbacks. | Used for event-driven programming. |
Common Beginner Mistakes
- Creating custom delegates when Action or Func is sufficient.
- Forgetting to unsubscribe from events.
- Invoking events without null checks.
- Using events for simple method calls.
- Creating overly complex event chains.
Best Practices
- Use Action and Func whenever possible.
- Use events for notifications.
- Keep event handlers lightweight.
- Unsubscribe from long-lived events.
- Use meaningful delegate names.
- Avoid excessive event nesting.
Frequently Asked Questions
Are delegates and events the same?
No. Events are built on top of delegates and provide controlled access to delegate invocation.
Should I use Action instead of custom delegates?
In many cases, yes. Action and Func simplify code and reduce the need for custom delegate types.
Where are events commonly used?
Events are used extensively in UI frameworks, game development, notifications, and event-driven architectures.
Related Tutorials
- Generics in C#
- Understanding Tasks in .NET
- Thread vs Task in C#
- Async and Await in C#
- Exception Handling in C#
- Best C# Coding Practices
Conclusion
Delegates and Events are essential concepts for building modern C# applications. Delegates enable flexible method execution, while events support communication between components through notifications.
By understanding custom delegates, Action, Func, Predicate, and event handling patterns, you'll be better prepared to develop scalable and maintainable .NET applications.