Delegates and Events in C#


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.

Multicast delegates

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.

Notification System with Multicast Delegates

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.

Delegates in C#

Step-by-Step Implementation

  1. Define the Delegate - Create a delegate type that represents the signature of the notification methods.
  2. Define the Subscriber Classes - Create classes representing Mobile and Email services, which will receive notifications.
  3. Create and Use Multicast Delegates - Combine multiple methods into a single delegate and invoke it.

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

Delegates in C#

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.

Event Delegates in C#

It will remove all the subscribed methods as shown in below image of above code.

Event Delegates in C#

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 Delegates 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

  1. Decoupling our applications, or rather creating loosely coupled applications
  2. Implementing mechanisms for communication between objects
  3. Providing a simple yet effective way to extend the application without changing the existing code
  4. Loosely coupled applications are easily extendable and we want to be able to do that without breaking the existing code.

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.

Event Delegates in C#

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:

  1. Define a delegate
  2. Define an event that relies on that delegate
  3. Raise an event

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

Event Delegates in C#

Benefits of Using Event Delegates

  1. Encapsulation and Safety

    • The event restricts invocation to within the Publisher class, ensuring that external code cannot invoke it directly.
    • External code can only subscribe to or unsubscribe from the event, but cannot reset it.
  2. Controlled Subscriptions

    • Only the Publisher class can raise the event, ensuring that notifications are published in a controlled manner.
    • Subscribers cannot interfere with each other by resetting the delegate or invoking it directly.
  3. Publisher-Side Invocation

    • The event delegate ensures that only the Publisher class can control when and how notifications are published.

Prev Next