In this article we are going to discuss how to implement delegates and Events with example in C#. Also we will explain The problem with the Multicast delegates and why need events with delegate to remove that problem.
It holds the references of more than one method. When a multicast delegate is invoked, it calls each of its assigned methods in the order they were added. To combine the delegates we can use the + operator.
Let's see a scenario where we have a Facebook class that publishes notifications, and Mobile and Email classes that receive these notifications. We'll implement this using multicast delegates.
Example
using System;
namespace delegateproject
{
public delegate void NotificationHandler(string message);
public class Publisher
{
public static void PublishNotification(string message, NotificationHandler notify)
{
Console.WriteLine($"Facebook: Publishing notification: {message}");
notify?.Invoke(message);
}
}
public class Mobile
{
// Method to handle the notification
public void ReceiveNotification(string message)
{
Console.WriteLine($"Mobile: Received notification: {message}");
}
}
public class Email
{
// Method to handle the notification
public void ReceiveNotification(string message)
{
Console.WriteLine($"Email: Received notification: {message}");
}
}
public class Program
{
public static void Main()
{
Publisher Publisher = new Publisher();
// Create instances of the subscribers
Mobile mobile = new Mobile();
Email email = new Email();
// Create a multicast delegate
NotificationHandler notify = null;
// Add methods to the multicast delegate
notify += mobile.ReceiveNotification;
notify += email.ReceiveNotification;
// Invoke the multicast delegate
Publisher.PublishNotification("New post from your friend!", notify);
Publisher.PublishNotification("New message received!", notify);
// Remove a method from the multicast delegate
notify -= mobile.ReceiveNotification;
// Invoke the multicast delegate again
Publisher.PublishNotification("Mobile unsubscribed, another post from your friend!", notify);
}
}
}
Output
The above example demonstrates how to use multicast delegates to invoke multiple methods with a single delegate. It shows how to add methods to a delegate, invoke the delegate, and remove methods from the delegate.
Problem with above Code(MultiCast Delegate)
But the problem with the above code is if Any external code can reset the delegate (e.g., notify = null), removing all the subscribed methods.
It will remove all the subscribed methods as shown in below image of above code.
The delegate can be invoked from outside the Publisher class, which should not happen. Only the Publisher should control when and how notifications are published. Publisher only sending notifications irrespective of subscriber interests.This is not ideal Publisher/Subscriber Model. First Subscribers has to subscribe for notification then only it should receive notifications.
So we will slightly modify above code to look like Publisher/Subscriber Model.
Using an event delegate addresses these issues by providing controlled access to the subscription mechanism and restricting the invocation of the delegate to within the Publisher class.
Delegate and Events in C#
Event in C#
Events are notifications. In simple words, we can say that it’s a message that goes out to one or more people (we can also say them as subscribers) who are listening. Obviously, it’s not going to be people in .NET, it will be objects.
So why do we exactly use events in C#?
Why Use Events
Example
The simplest example of an event is the button. If you have worked with C# and if you have done any kind of UI work at all like Windows Form Application, and Web Form Application, then you might be known that the button element has many events like click event, mouse over, mouse out, and many more.
Role of Delegates in C#
without delegates, the event would not be useful at all. And the reason is that we do not have other ways to transfer the event data from point A (Event Raiser) to point B (Event Handler).
So, let us proceed and try to understand what are exactly delegates and why they are used in .NET Framework.
on the left-hand side, we have the little Kid(girl )who is talking and on the right-hand side, her parent who is listening. So, in this case, we can say that the little girl is the Event Raiser and the parent who is listening is the Event Handler. And there is a pipeline between the Event Raiser and Event Handler and we call that pipeline a Delegate. The delegate is really what makes everything possible when it comes to raising an event and handling an event. It will make the link between the Event Raiser and Event Handler and without a delegate, it is not possible to Raise an Event and also not possible to handle an Event.
Source
Source is the class that will be publishing the event.
EventArgs
EventArgs which is nothing but our event data that we want to send from Point A(Kid) to Point B(Parent), and we are going to send the event data through the Pipeline. Now, the data (EventArgs) going over the pipeline and will reach the Event Handler.
Now let’s see how we do we implement an event in C#.
We need to do:
Example
using System;
namespace DelegateProject
{
// Define the delegate type for the event
public delegate void NotificationHandler(string message);
public class Publisher
{
// Declare the event using the delegate type
public event NotificationHandler NotificationPublished;
// Method to publish a notification
public void PublishNotification(string message)
{
Console.WriteLine($"Facebook: Publishing notification: {message}");
OnNotificationPublished(message);
}
// Protected method to raise the event
protected virtual void OnNotificationPublished(string message)
{
NotificationPublished?.Invoke(message);
}
}
public class Mobile
{
// Method to handle the notification
public void ReceiveNotification(string message)
{
Console.WriteLine($"Mobile: Received notification: {message}");
}
}
public class Email
{
// Method to handle the notification
public void ReceiveNotification(string message)
{
Console.WriteLine($"Email: Received notification: {message}");
}
}
public class Program
{
public static void Main()
{
Publisher publisher = new Publisher();
// Create instances of the subscribers
Mobile mobile = new Mobile();
Email email = new Email();
// Subscribe to the event
publisher.NotificationPublished += mobile.ReceiveNotification;
publisher.NotificationPublished += email.ReceiveNotification;
// Publish notifications
publisher.PublishNotification("New post from your friend!");
publisher.PublishNotification("New message received!");
// Unsubscribe from the event
publisher.NotificationPublished -= mobile.ReceiveNotification;
// Publish notification again
publisher.PublishNotification("Mobile unsubscribed, another post from your friend!");
}
}
}
Output
Encapsulation and Safety
Controlled Subscriptions
Publisher-Side Invocation