Prerequisite
Before diving into this article, please note that this is the first in the C# Advanced Series. It is recommended that you have at least 6 months of hands-on experience with C#. If you’re new or need a refresher, please explore the C# Fundamentals Series' Articles to build a solid foundation.
Introduction
Delegates in C# can be a challenging concept to grasp, but they open up a world of possibilities when it comes to writing flexible, reusable code. In this article, we'll break down what delegates are, how to use them, and why they are important in building modular and extendable applications. Additionally, you will find practical assignments at the end to solidify your understanding.
What Are Delegates?
A delegate in C# is like a pointer to a function—it defines a type-safe way to call a method without knowing its implementation. Delegates are especially useful when you need to pass methods as parameters, allowing for more dynamic and flexible code. In short, they provide a way to "delegate" work to another method.
Step-by-Step Example: Notification System
Step 1: Define the Delegate
First, define a delegate that specifies the signature of methods that will be used to notify users.
public delegate void NotifyUserDelegate(string message, string recipient);
Step 2: Create Notification Methods
Create different methods to handle different types of notifications, such as email, SMS, and push notifications:
public void SendEmail(string message, string email)
{
Console.WriteLine($"Email sent to {email}: {message}");
}
public void SendSMS(string message, string phoneNumber)
{
Console.WriteLine($"SMS sent to {phoneNumber}: {message}");
}
public void SendPushNotification(string message, string deviceId)
{
Console.WriteLine($"Push notification sent to device {deviceId}: {message}");
}
Step 3: Create a Method to Use the Delegate
Create a method that takes a delegate as a parameter to notify users using different methods.
public void NotifyUser(NotifyUserDelegate notifyMethod, string message, string recipient)
{
notifyMethod(message, recipient); // Invoke the method passed as a delegate
}
Step 4: Assign Methods to the Delegate and Call NotifyUser
Finally, assign different notification methods to the delegate and use it to notify users.
NotifyUserDelegate emailNotifier = SendEmail;
NotifyUserDelegate smsNotifier = SendSMS;
NotifyUserDelegate pushNotifier = SendPushNotification;
NotifyUser(emailNotifier, "Your order has been shipped!", "user@example.com");
NotifyUser(smsNotifier, "Your package is out for delivery.", "+123456789");
NotifyUser(pushNotifier, "Your order has been delivered!", "device12345");
Full Code for Notification System Example
using System;
public class NotificationExample
{
// Step 1: Define the delegate
public delegate void NotifyUserDelegate(string message, string recipient);
// Step 2: Create notification methods
public void SendEmail(string message, string email)
{
Console.WriteLine($"Email sent to {email}: {message}");
}
public void SendSMS(string message, string phoneNumber)
{
Console.WriteLine($"SMS sent to {phoneNumber}: {message}");
}
public void SendPushNotification(string message, string deviceId)
{
Console.WriteLine($"Push notification sent to device {deviceId}: {message}");
}
// Step 3: Create a method to use the delegate
public void NotifyUser(NotifyUserDelegate notifyMethod, string message, string recipient)
{
notifyMethod(message, recipient); // Invoke the method that was passed as a delegate
}
// Step 4: Run the example
public void RunExample()
{
NotifyUserDelegate emailNotifier = SendEmail;
NotifyUserDelegate smsNotifier = SendSMS;
NotifyUserDelegate pushNotifier = SendPushNotification;
// Notify via email
NotifyUser(emailNotifier, "Your order has been shipped!", "user@example.com");
// Notify via SMS
NotifyUser(smsNotifier, "Your package is out for delivery.", "+123456789");
// Notify via push notification
NotifyUser(pushNotifier, "Your order has been delivered!", "device12345");
}
// Entry point
public static void Main()
{
NotificationExample example = new NotificationExample();
example.RunExample();
}
}
Benefits of Using Delegates
- Flexibility: You can decide at runtime how to perform certain actions.
- Extensibility: Easily add new functionalities without changing the existing code.
- Modularity: Delegates help you decouple your code, making it more reusable and maintainable.
Assignments
Easy Level
-
Objective: Implement a
Calculator
using delegates. -
Instructions:
- Define a delegate named
MathOperation
that takes two integers and returns an integer. - Create methods for addition, subtraction, multiplication, and division.
- Write a method named
PerformOperation
that takes aMathOperation
delegate and two integers and uses it to perform the operation.
- Define a delegate named
Example Usage:
PerformOperation(addition, 5, 3); // Output: 8
Medium Level
- Objective: Build a simple Event Logger using delegates.
-
Instructions:
- Define a delegate named
LogHandler
that takes a string message. - Create different logging methods, such as
ConsoleLogger
to log to the console andFileLogger
to log to a text file. - Use a method named
LogEvent
that takes aLogHandler
and logs various events, such as "User logged in", "File uploaded", etc.
- Define a delegate named
Example Usage:
LogEvent(ConsoleLogger, "User logged in"); // Logs to console
LogEvent(FileLogger, "File uploaded"); // Logs to file
Difficult Level
- Objective: Create a Workflow Engine using delegates.
-
Instructions:
- Define a delegate named
WorkflowStep
that takes no parameters and returns nothing. - Create methods that represent different steps of a workflow, such as
StartProcess
,ProcessData
, andEndProcess
. - Write a method named
RunWorkflow
that takes an array ofWorkflowStep
delegates and runs each step sequentially.
- Define a delegate named
Example Usage:
WorkflowStep[] workflowSteps = { StartProcess, ProcessData, EndProcess };
RunWorkflow(workflowSteps); // Runs each step in sequence
Conclusion
Delegates can add a lot of power to your applications, making them more flexible and easier to extend. By working through the example and completing the assignments, you'll gain a solid understanding of how delegates work and how you can use them to write more modular code.
Call to Action
Did you enjoy this step-by-step guide? Try out the assignments and see how far you can push the flexibility of your code with delegates. Feel free to share your solutions and challenges in the comments below!
Top comments (3)
i am bookmarking this for sure , that is a good reference for delegates example which i always forgot as a c# developer
@moh_moh701 Nice explanation! particularly this line,
@dotnetfullstackdev thanks