Events in C#

Introduction

C# has provides event driven programming by adding support through Events. It is a way to provide notifications to client when something happens to an object. It is an encapsulation of idea that "Something happened". Events and Delegates are tightly coupled concept because event handling requires Delegate for the dispatch of Event.

The class that send or raises the event is called "Publisher" and class that receives or handle the event is called "Subscriber".

Below is the UML - Class Diagram of "Publisher-Subscriber" or Event Driven concepts:

UML - Class Diagram

Below are the key points about Events:

Following are the key points about Event:

  1. Event Handlers in C# return void and take two parameters.
  2. The First parameter of Event - Source of Event means publishing object.
  3. The Second parameter of Event - Object derived from EventArgs.
  4. The publishers determines when an event is raised and the subscriber determines what action is taken in response.
  5. An Event can have so many subscribers.
  6. Events are basically used for the single user action like button click.
  7. If an Event has multiple subscribers then event handlers are invoked synchronously.

Syntax for the declaration of Event:

  1. public event EventHandler MyEvent;  
Steps for implementing Event:

To declare an event inside a class, first a Delegate type for the Event must be declared like below:
  1. public delegate void MyEventHandler(object sender, EventArgs e);  
Declare Event:
  1. public event MyEventHandler MyEvent;  
Invoking an Event:
  1. if (MyEvent != null) MyEvent(this, e);  
Invoking an Event can only be done from within the class that declared the Event.

Hooking up Event:
  1. MyEventClass.MyEvent += new ChangedEventHandler(MyEventChanged);  
Now, Detach the event:
  1. MyEventClass.MyEvent -= new ChangedEventHandler(MyEventChanged);  
Add/Remove Operation in Events

Below is the example of an Event - System.EventHandler Delegate type:
  1. public class MyTest  
  2. {  
  3.     public event EventHandler MyEvent  
  4.     {  
  5.         add  
  6.         {  
  7.             Console.WriteLine("add operation");  
  8.         }  
  9.         remove  
  10.         {  
  11.             Console.WriteLine("remove operation");  
  12.         }  
  13.     }  
  14. }  
  15. public class Test  
  16. {  
  17.     public void TestEvent()  
  18.     {  
  19.         MyTest myTest = new MyTest();  
  20.         myTest.MyEvent += myTest_MyEvent;  
  21.         myTest.MyEvent -= myTest_MyEvent;  
  22.     }  
  23.     public void myTest_MyEvent(object sender, EventArgs e)  
  24.     {  
  25.     }  
  26. }  
  27. static void Main(string[] args)  
  28. {  
  29.     Test test = new Test();  
  30.     test.TestEvent();  
  31.     Console.ReadKey();  
  32. }  
Output:

add operation
remove operation

Event - Basic Conceptual Implementation

Below implementation will show message whenever new item into ArrayList will be added.
  1. public delegate void EventHandler(object sender, EventArgs e);  
  2. public class Publisher: ArrayList  
  3. {  
  4.     public event EventHandler ProdcutAddedInfo;  
  5.     protected virtual void OnChanged(EventArgs e)  
  6.     {  
  7.         if (ProdcutAddedInfo != null) ProdcutAddedInfo(this, e);  
  8.     }  
  9.     public override int Add(Object product)  
  10.     {  
  11.         int added = base.Add(product);  
  12.         OnChanged(EventArgs.Empty);  
  13.         return added;  
  14.     }  
  15.     public override void Clear()  
  16.     {  
  17.         base.Clear();  
  18.         OnChanged(EventArgs.Empty);  
  19.     }  
  20.     public override object this[int index]  
  21.     {  
  22.         set  
  23.         {  
  24.             base[index] = value;  
  25.             OnChanged(EventArgs.Empty);  
  26.         }  
  27.     }  
  28. }  
Now,
  1. public class Subscriber  
  2. {  
  3.     private Publisher publishers;  
  4.     public Subscriber(Publisher publisher)  
  5.     {  
  6.         this.publishers = publisher;  
  7.         publishers.ProdcutAddedInfo += publishers_ProdcutAddedInfo;  
  8.     }  
  9.     void publishers_ProdcutAddedInfo(object sender, EventArgs e)  
  10.     {  
  11.         if (sender == null)  
  12.         {  
  13.             Console.WriteLine("No New Product Added.");  
  14.             return;  
  15.         }  
  16.         Console.WriteLine("A New Prodct Added.");  
  17.     }  
  18.     public void UnSubscribeEvent()  
  19.     {  
  20.         publishers.ProdcutAddedInfo -= publishers_ProdcutAddedInfo;  
  21.     }  
  22. }  
Execute Code:
  1. class Program  
  2. {  
  3.     static void Main(string[] args)  
  4.     {  
  5.         Publisher publisher = new Publisher();  
  6.         Subscriber subscriber = new Subscriber(publisher);  
  7.         publisher.Add(new Product  
  8.         {  
  9.             ProductName = "Complan", Price = 20  
  10.         });  
  11.         publisher.Add(new Product  
  12.         {  
  13.             ProductName = "Horlics", Price = 120  
  14.         });  
  15.         publisher.Add(new Product  
  16.         {  
  17.             ProductName = "Boost", Price = 200  
  18.         });  
  19.         subscriber.UnSubscribeEvent();  
  20.         Console.ReadKey();  
  21.     }  
  22. }  
Output:

A New Product Added.
A New Product Added.
A New Product Added.


Question: Can we use Events without Delegate?

Answer: No, Events use Delegates internally. Events are encapsulation over Delegates. There is already defined Delegate "EventHandler" that can be used like below: 
  1. public event EventHandler MyEvents;  
So, it also used Delegate Internally.

I have attached sample code. Read and debug the code very carefully so you will understand the concept of Event in C#.