Monday, February 3, 2014

Delegates and Events in C# / .Net Simplified : C# Tutorial

This tutorial I will explain all the basics of C# Delegates & Events,Where to use Delegates in our daily projects.
You might read so many definitions like
  • C# Delegate similar to functional pointer in C++ but type safe
  • A delegate can point to a method, which is having same signature as that of the delegate.
  • With the use of delegates we can call methods asynchronously.
  • Delegates and events can be used to implement publisher-Subscriber models.   labla labla labla……………………….
What are Delegates and Events in C#
What are Delegates and Events in C#
But What is the purpose of having delegates & Events in C#? If you understand the use of delegates,events then we can apply them in our daily projects.
In this tutorial I will try to explain the use of delegates & Events with simple C# examples so that at the end of this post you will have clear picture on Delegates and Events.
See the below example

Our client(say console application) will use above Calculator class to do maths operations. Console application will take two arguments

The Code looks fine and it will work perfectly but if you observe carefully client (console application) and our class are tightly coupled.
Say for example I want to calculate LCM (Least Common Multiple) of two numbers. We will add method in Calculator class and call that method in our client(Console application).

Both are tightly coupled that means both Class and Client needs to be compiled in order to affect the changes.
This problem can be solved with the use of Delegates. Before that I will explain a simple delegate example and then will solve the above problem

A Simple C# Delegate:

Follow the below steps to create a Delegate
  • Define  : Define a Delegate
  • Create  : Create a Delegate object to assign
  • Refer or Point : Point to reference of a Method
  • Invoke : Finally Call or Invoke the delegate
Delegates definition syntax

For example see the below example.”SumDelegate” is a delegate which can refer functions which takes two integer parameters and returns one integer.

Create a Delegate Object

We will use the above delegate to Call sum method which will add two numbers. In third steps we have to assign delegate to reference of a method

And in the final step invoke the delegate

Final example

So What is the advantage? We can directly call the Sum method right why we have to use Delegate?
With the use of Delegates we call or assign methods at run time. How?
Going back to our problem we will slightly modify our Calculator as shown below

We Declare a Delegate “CalculatorDelegate” which takes two int parameters and returns int.This delegate can refer methods like Add,Sub,Multi,Div etc.

The above method GetDelegateRef() is used to get delegate reference i.e., which method to call(Add,Sub,Multi etc)  based upon request from clients.
We will modify our client code slightly as shown below

Console client will take three arguments first argument decides which operation to perform and 2nd , 3rd arguments are used for calculations.
And for invoking
With the use of GetDelegateRef() method at run time we will know which method to call and then Invokes the delegate.
Now if you want to Add LCM operation simply add it to Calculator Class (if intoperation=5 assign delegate to LCM method) and no need to change any code at client side, at run time we will decide which operation to invoke. No need to compile client code.
That means we are decoupling client from our Class with the help of Delegates. Whenever we introduce any features try to avoid changes at client side

Multicast Delegate in C# :

In the above example the delegate object pointing to single function or method at a time.
But delegate object has the capability of holding multiple method references and whenever we invoke delegate object it will call those methods one by one. That is Called “Multicast delegate”(Naming convention only).
We will be having only a Delegate depending upon its usage we call it either Delegate or Multicast Delegate. See the below example

Purpose Of Multicast Delegate in C#:

So where we  can use multicast delegates in our daily projects.Everyone will have Facebook account rite. Whenever we get any notifications we will be receiving SMS and as well as emails.
Facebook will publish notifications and we will receive notifications to Mobile and Email.This is like publisher and subscriber Model.
publisher And SubscriberDelegate
Publisher And Subscriber Delegate
In this kind of publisher & Subscribers model we can use Multicast Delegates. We will go through one simple example to understand it better.

The Code is easy to Understand I declared two Subscribers “SendViaEmail” and “SendViaSMS”. And in publisher class I declared one Delegate which takes string parameter and returns void.
And For invoking delegate I wrote one more method called “PublishMethod”  (You will understand why I wrote this method at the end of this post)
And To test the application we will write one Console Application

But the problem with the above code is it’s more over like “Master and Slave model”.
That means You are not subscribed to Mobile notifications but still Facebook sending notifications to your mobile.
In the above code subscribers do not have rights to decline notifications.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.

I added one method called Subscribe() which takes Publisher Object as parameter and decides whether to receive notifications or not.Subscribe Method assigns Delegate to corresponding methods(I declared Method as private).And it can assign any number of methods to delegate like For example “SendViaMobile” wants to save the notifications in Log files So internally it can define one method which is same signature as Delegate and assign it to Delegate Object.
So in our console application we have to call subscribe method before invoking the delegate.

“SendViaEmail” not subscribed(I put it in comments) to notifications so it wont receive any notifications.
So far everything is Good But here we are ignoring one serious issue “We are exposing Delegate to Subscribers” So what ? what happens if we expose to subscribers?
In the the above code “SendViaMobile” class, In subscribe method I wrote one Line
//pub.publishmsg = null;

Just remove the comment line that means we assigning delegate object to ‘null’
And in our client code
Publisher publisher = new Publisher();
SendViaMobile SM = new SendViaMobile();
SendViaEmail SE = new SendViaEmail();
SE.Subscribe(publisher);
SM.Subscribe(publisher);
publisher.PublishMessage(“Hello You have new Notifications”);
First I subscribed Email and then mobile. But In Mobile Subscribe class we assigned delegate to null. That means even Email also do not receive any notifications.
And also Subscriber can invoke our delegate.
C# Delegate Problem
C# Delegate Problem

that means we are violating Encapsulation principle
So What is the solution?
  • We should not expose delegate to subscribe (In that case it will become Master Slave Model)
  • If we expose also we should not give permissions to subscriber to change or invoke delegate.That means it should only assign some methods or functions to Delegate.
The Second solution seems to be good right. That’s how Events Came into Picture.

The purpose of Events and Delegates in C#:

As explained above Events can solve the problem of exposing delegates to subscribers to achieve ideal Publisher/Subscriber Model.
See the below example

The invoking and everything is same as above
And if want to change  or invoke delegate from other classes it will throw following error
Delegate and Events in C#
Delegate and Events in C#
That means we cannot invoke or change the delegate event in outside classes other than Publisher Class. That’s the reason I wrote PublishMessage() method in Publisher class. This method will invoke the delegate event internally. The outside classed can call PublishMessage() method to invoke delegate.
  • Events are invoked in within the class itself.
  • Outside classes do not have access to invoke the Delegate Event.
  • It can appear only on left hand side of += or -= that means only appending or removing allowed No assignment.
That means Event will hide the sensitive data of Delegate and exposes necessary data to outside world.This is the ideal example of Encapsulation principle in OOPS.
I hope you understand the difference between Delegates and Events in C#.
One more use of Delegates is it’s used to call methods asynchronously.

Delegates and Asynchronous Method Calls:

What are Asynchronous method calls? Some times we need to perform a large task. But we don’t want to wait till the task ends so that we can perform other tasks.
And whenever the large task ends we need to receive a notification whether it is success or not. In real world we call this as asynchronous execution of task.
We can easily achieve this with the use of Delegates.

The code is straight forward and easy to understand
  • Assigned LargeTask() to delegate object.
  • Invoke delegate using .BeginInvoke()
  • First parameter is callback mechanism(In our case ‘CallBackLargeTask’) and second one is delegate object.
  • Callback mechanism is responsible for sending notification back to client.
  • We will use .EndInvoke() Method to get the success message.
To Unlock the source code please share this article

No comments:

Post a Comment