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
Next, 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!", "moc.elpmaxe @resu");
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);
<span class="c1">// Step 2: Create notification methods</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">SendEmail</span><span class="p">(</span><span class="kt">string</span> <span class="n">message</span><span class="p">,</span> <span class="kt">string</span> <span class="n">email</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">$"Email sent to </span><span class="p">{</span><span class="n">email</span><span class="p">}</span><span class="s">: </span><span class="p">{</span><span class="n">message</span><span class="p">}</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">SendSMS</span><span class="p">(</span><span class="kt">string</span> <span class="n">message</span><span class="p">,</span> <span class="kt">string</span> <span class="n">phoneNumber</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">$"SMS sent to </span><span class="p">{</span><span class="n">phoneNumber</span><span class="p">}</span><span class="s">: </span><span class="p">{</span><span class="n">message</span><span class="p">}</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">SendPushNotification</span><span class="p">(</span><span class="kt">string</span> <span class="n">message</span><span class="p">,</span> <span class="kt">string</span> <span class="n">deviceId</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">$"Push notification sent to device </span><span class="p">{</span><span class="n">deviceId</span><span class="p">}</span><span class="s">: </span><span class="p">{</span><span class="n">message</span><span class="p">}</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// Step 3: Create a method to use the delegate</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">NotifyUser</span><span class="p">(</span><span class="n">NotifyUserDelegate</span> <span class="n">notifyMethod</span><span class="p">,</span> <span class="kt">string</span> <span class="n">message</span><span class="p">,</span> <span class="kt">string</span> <span class="n">recipient</span><span class="p">)</span>
<span class="p">{</span>
<span class="nf">notifyMethod</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">recipient</span><span class="p">);</span> <span class="c1">// Invoke the method that was passed as a delegate</span>
<span class="p">}</span>
<span class="c1">// Step 4: Run the example</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">RunExample</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">NotifyUserDelegate</span> <span class="n">emailNotifier</span> <span class="p">=</span> <span class="n">SendEmail</span><span class="p">;</span> <span class="c1">// Assign SendEmail to delegate</span>
<span class="n">NotifyUserDelegate</span> <span class="n">smsNotifier</span> <span class="p">=</span> <span class="n">SendSMS</span><span class="p">;</span> <span class="c1">// Assign SendSMS to delegate</span>
<span class="n">NotifyUserDelegate</span> <span class="n">pushNotifier</span> <span class="p">=</span> <span class="n">SendPushNotification</span><span class="p">;</span> <span class="c1">// Assign SendPushNotification to delegate</span>
<span class="c1">// Notify via email</span>
<span class="nf">NotifyUser</span><span class="p">(</span><span class="n">emailNotifier</span><span class="p">,</span> <span class="s">"Your order has been shipped!"</span><span class="p">,</span> <span class="s">"[email protected]"</span><span class="p">);</span>
<span class="c1">// Notify via SMS</span>
<span class="nf">NotifyUser</span><span class="p">(</span><span class="n">smsNotifier</span><span class="p">,</span> <span class="s">"Your package is out for delivery."</span><span class="p">,</span> <span class="s">"+123456789"</span><span class="p">);</span>
<span class="c1">// Notify via push notification</span>
<span class="nf">NotifyUser</span><span class="p">(</span><span class="n">pushNotifier</span><span class="p">,</span> <span class="s">"Your order has been delivered!"</span><span class="p">,</span> <span class="s">"device12345"</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// Entry point</span>
<span class="k">public</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">Main</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">NotificationExample</span> <span class="n">example</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">NotificationExample</span><span class="p">();</span>
<span class="n">example</span><span class="p">.</span><span class="nf">RunExample</span><span class="p">();</span>
<span class="p">}</span>
}
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.
[fluentform id="8"]