Events and event handlers are generally used in case of a Publisher-Subscriber design pattern where some kind of event has occurred in a particular class and it needs to notify other classes about the event. The Publisher class has an event which gets invoked on some condition, the subscribers are notified based on their subscription. One Key benefit of this is the publisher does not need to know anything about who gets notified.
Syntax :
event EvenHandler handler_name;
EventHandler is a delegate. To subscribe to this event a class must have a method with void return type and two input parameters of types :
- Object – The source or publisher who invoked the event.
- EventArgs – An object class which contains the event information.
Syntax for Delegate Method:
public void method_name(Object sender, EventArgs e);
Note: The Subscriber must have a method of same signature as described above in order to receive the event notification from the publisher.
Syntax for Subscribe to an Event:
publisher.eventhandler_name += new EventHandler(subscriber_method_with_same_signature);
Syntax to Unsubscribe from an Event:
publisher.eventhandler_name -= new EventHandler(subscriber_method_with_same_signature);
Let’s understand this with an example. Suppose we have a Channel class and two Subscriber classes. Whenever a video is uploaded on the channel. Both the subscribers should get the notification about the video upload. In this case Channel will work as a Publisher and raise the event. The subscribers who have subscribed to the event will receive the event raised through event handlers.
Key Logic :
- The Channel class will have an event. We will trigger it at some condition.
- Subscriber will have a method to receive the event. We will attach(subscribe) this method to the channel class’s event, so that whenever the event is invoked the subscriber’s method gets executed automatically.
Example 1:
// C# program for Illustrating Handling an // Event Declared in an Interface through C# using System;
using System.Collections.Generic;
namespace GFG {
// <summary>
// Video class
// </summary>
public class Video {
public string Name;
}
// Interface IChannel has an event VideoAdded
public interface IChannel {
event EventHandler VideoAdded;
}
// Channel class - A Publisher of the event
public class Channel : IChannel
{
public event EventHandler VideoAdded;
public string Name
{
get ;
set ;
}
public List<Video> ListOfVideos = new List<Video>();
public void AddVideo()
{
Video video = new Video();
video.Name = "EventHandler in c#" ;
ListOfVideos.Add(video);
// Notify all the subscribers
NotifyAllSubscribers();
}
public void NotifyAllSubscribers()
{
EventHandler handler = VideoAdded;
// safety check to avoid null reference error
if (handler != null ) {
// Invoking the event VideoAdded.
// 1st parameter - sender object i.e Channel
// class in this case 2nd parameter - object of
// type EventArgs()
handler( this , new EventArgs());
}
}
}
// receiver 1
public class Subscriber_A {
public string Name
{
get ;
set ;
}
public Subscriber_A(Channel ch)
{
// Subscribing to the publisher's event
ch.VideoAdded
+= new EventHandler(ReceiveVideoNotification);
}
// Method that is to be executed when the event is
// triggered.
public void ReceiveVideoNotification( object sender,
EventArgs e)
{
Console.WriteLine(
"Hello {0}, a new video has
been uploaded by GeeksForGeeks",
Name);
Console.WriteLine();
}
}
// receiver 2
public class Subscriber_B {
public string Name
{
get ;
set ;
}
public Subscriber_B(Channel channel)
{
// Subscribing to the publisher's event
channel.VideoAdded
+= new EventHandler(ReceiveVideoNotification);
}
// Method that is to be executed when the event is
// triggered.
public void ReceiveVideoNotification( object sender,
EventArgs e)
{
Console.WriteLine(
"Hello {0}, a new video has been
uploaded by GeeksForGeeks",
Name);
Console.WriteLine();
}
}
class Program {
static void Main( string [] args)
{
Channel channel = new Channel();
channel.Name = "GeeksForGeeks" ;
Subscriber_A A = new Subscriber_A(channel);
A.Name = "Geek_1" ;
Subscriber_B B = new Subscriber_B(channel);
B.Name = "Geek_2" ;
// Adding a video
channel.AddVideo();
}
}
} |
Output:
Note : The order in which the subscriber objects are created will be preserved while receiving event notification.