This article describes basics about delegate and events and later shows how it can be used in project or real time scenario.
Introduction
In my last
article I wrote about practical use of delegate , however the article was
incomplete, you can find the article at the below url.
http://www.dotnetfunda.com/articles/article1107-practical-use-of-delegate-in-real-time-application-1-.aspx
This time I
have spent some time to write a complete article on delegate to event with
practical use. This article explains basics of delegate first with simple
example and then concentrates on how we
can practically use event and delegate in a project . If you find any
improvement/comment feel free to email me at esensahoo@gmail.com.
What is delegate ?
Ø
It defines
prototype for functions
Means delegate defines the signature/parameter types
and the return type for functions
Ex - delegate void
Print(string
Name);
Why Delegate?
Ø In
C# every variable/data is associated to a type and has a value.Similarly
Delegate is a type for methods/functions.
Ex:-
int i; -> i is a variable of type int
i = 10; -> i represents a value 10
|
Print p; -p is a variable of type Print
p = new Print(PrintHi);
- p represents function PrintHi
off course we have to
define the function PrintHi with same signature as delegate Print.
void PrintHi(string name)
{
Console.WriteLine("Hi.."+name);
}
Now both PrintHi("John"); and p("John"); will give same output
“Hi.. John”
|
Ø
Delegate being a method type enables us to set a
concrete method as a property or pass a concrete method as a parameter like
other type variables.
Ex:
class X
{
public
int p;
public
void writeTriple(int
q)
{
Console.WriteLine(q*3);
}
}
X o = new X();
o.p = 10;
int q=5;
o.writeTriple(q);
|
class X
{
public
Print p;
public
void SayHi(Print
q)
{
q("John");
}
}
X o = new X();
o.p = new Print(PrintHi);
Print q = new Print(PrintHi);
o.SayHi(q);
|
Show me a complete program on Delegate?
//Step-1 Declare a delegate
delegate void
Print(string
Name);
//Step-2 Define
a method for delegate having same signature
void PrintHi(string name)
{
Console.WriteLine("Hi.."+name);
}
//Step-3 Create
an instance of delegate by associating concrete method
Print p = new Print(PrintHi);
//Step-4 Invoke
the delegate
p("John");
Putting all
the steps together in a program:
class Program
{
//Step-1 Declare a delegate
delegate
void Print(string Name);
//Step-2
Define a method for delegate having same signature
static void PrintHi(string
name)
{
Console.WriteLine("Hi.." + name);
}
static void Main(string[]
args)
{
//Step-3
Create an instance of delegate by associating concrete method
Print
p = new Print(PrintHi);
//Invoke
the delegate
p("John");
}
}
Output Will
be “Hi..John” as shown below
What is multi casting in Delegate?
Ø
Associating multiple functions to a delegate
instance is called multicasting
Ø
In multicasting single invoke on the delegate
instance executes all the functions in the order they are associated with the
delegate instance.
Ex:
class Program
{
delegate
void Print(string Name);
static void PrintHi(string
name)
{
Console.WriteLine("Hi.." + name);
}
static void PrintBye(string
name)
{
Console.WriteLine("Bye.." + name);
}
static void Main(string[]
args)
{
//Associating
multiple methods to delegate instance
Print p = new Print(PrintHi);
p += new Print(PrintBye);
p("John");
}
}
Output :

What is Anonymous method in delegate? Or What is inline delegate
declaration?
Associating
the method body in line with the delegate instance instead of using named
methods.
Ex:
class Program
{
delegate
void Print(string Name);
static void Main(string[] args)
{
//Defining
the methid body inline
Print p = delegate(string name) { Console.WriteLine("Hi.." + name); };
p("John");
Console.Read();
}
}
Output will
be same “Hi..John”.
Give me a scenario where I can use delegate?
In the below example I have
shown a User class. Client will use this class to create and register a user , however
it entirely depends on the client to implement how they
want to notify users about their registration userid and PIN via email or via
SMS.
namespace
RegistrationModule
{
public delegate void NotifyUser(ContactDetail objContact,string
Notification);
public class User
{
public string Name;
public
int Age;
public
ContactDetail Contact=new ContactDetail();
public NotifyUser Notify;
public
void Register()
{
//code
to save the user details to the database
//
and generate userID
string
userID=(new Random()).Next(1111,5555).ToString();
Console.WriteLine("User details saved to database.");
Notify(Contact,"Registred
Successfully,Your UserID is:"+userID);
//Code
to generate random 4 digit T-pin
string
PIN=(new Random()).Next(5555,9999).ToString();
Notify(Contact, "Your
PIN is " + PIN);
}
}
public class ContactDetail
{
public
string Email;
public
string MobNo;
}
}
Lets say first client
wants to send SMS to notify their user.So below will be
their implementation.
I have given the comment to explain the code.
class Program
{
static void Main(string[]
args)
{
User
usr = new User();
usr.Name = "satya";
usr.Age = 29;
usr.Contact.Email = "satya@test.com";
usr.Contact.MobNo = "997766553";
usr.Notify = new NotifyUser(SendSMS);
usr.Register();
Console.Read();
}
//Below
function is having same signature as delegate NotifyUser and will be attached
to the delegate.
static void SendSMS(ContactDetail
objContact,string NotificationMsg)
{
string
MobNo = objContact.MobNo;
//Add
your code to send NotificationMsg to the user mobile number.
Console.WriteLine("SMS Sent to" + MobNo);
}
}
OutPut:

Now lets say the second client
wants to notify the user via email:
class Program
{
static void Main(string[]
args)
{
User
usr = new User();
usr.Name = "satya";
usr.Age = 29;
usr.Contact.Email = "satya@test.com";
usr.Contact.MobNo = "997766553";
usr.Notify = new NotifyUser(SendEmail);
usr.Register();
Console.Read();
}
//Below
function is having same signature as delegate NotifyUser and will be attached
to the delegate.
static void SendEmail(ContactDetail
objContact, string NotificationMsg)
{
string
email = objContact.Email;
//Add
your code to send NotificationMsg to the user email.
Console.WriteLine("email Sent to" + email);
}
}
That's it. Now client-1 user will get userid and password via SMS
and client-2 will get userid and password via email. Important thing to notice
here is SendSMS and SendEmail is the code written by the client however it is
invoked by the User class what in other words we can say delegates
allow us to inject functionality.
Show me a
scenario where I can use multi-casting ?
In the above scenario let’s say the client wants to send the notification
both via email and SMS, well below is the simple change he has to make.
usr.Notify = new NotifyUser(SendSMS);
usr.Notify += new NotifyUser(SendEmail);
usr.Register();
What is
an Event?
Ø Event provides a way for objects to notify state change or any
action.
Ø Technically events are delegate instance declared with event
keyword.
Ex :
delegate void
Print();
event Print
OnStartPrint;
Why
Events? Can not delegate do the same thing?
Yes delegate can do the same
thing, but does not give abstraction. Means client can invoke the delegate
where ever they want ,but event won’t allow that.
Show me a
practical example showing difference between event and delegate?
Let’s
consider our above example of user registration.
class Program
{
static void Main(string[]
args)
{
User
usr = new User();
usr.Name = "satya";
usr.Age = 29;
usr.Contact.Email = "satya@test.com";
usr.Contact.MobNo = "997766553";
usr.Notify = new NotifyUser(SendEmail);
usr.Register();
Console.Read();
}
static void SendEmail(ContactDetail
objContact, string NotificationMsg)
{
string
email = objContact.Email;
//Add
your code to send NotificationMsg to the user email.
Console.WriteLine("email Sent to" + email);
}
}
Looks good
with delegate , but what if the client
uses the below code.
class Program
{
static void Main(string[]
args)
{
User
usr = new User();
usr.Name = "satya";
usr.Age = 29;
usr.Contact.Email = "satya@test.com";
usr.Contact.MobNo = "997766553";
usr.Notify = new NotifyUser(SendEmail);
usr.Notify(usr.Contact, "Your TPIN is 1234");
//usr.Register();
Console.Read();
}
static void SendEmail(ContactDetail
objContact, string NotificationMsg)
{
string
email = objContact.Email;
//Add
your code to send NotificationMsg to the user email.
Console.WriteLine("email Sent to" + email);
}
}
Output:

Now the SMS is sent even though the user is not registered.
So now a question, should we allow the client
to write the below line of code, ie should we give access to him to invoke the
delegate?
usr.Notify(usr.Contact, "Your TPIN is 1234");
Off course NO, in our case because only User.Register()
method knows when userid is created and
when password is created ,so no one other than User class should be allowed to
invoke the delegate.
So how do we fix this
problem...simple use event. By declaring the Notify as event user will get
compilation error if he attempts to invoke the event by below line
usr.Notify(usr.Contact, "Your TPIN is 1234");
So what changes we have
to make in our program?
1. Just
add the event keyword before the delegate name NotifyUser in the
RegistrationModule.User class as below.
public
event NotifyUser Notify;
2. Use += instead of = for
initializing events i.e
usr.Notify += new NotifyUser(SendEmail);
Show me the Complete Program ?
namespace
RegistrationModule
{
public delegate void NotifyUser(ContactDetail
objContact,string Notification);
public class User
{
public
string Name;
public
int Age;
public
ContactDetail Contact=new ContactDetail();
public event NotifyUser Notify;
public
void Register()
{
//code to save the
user details to the database
//
and generate userID
string
userID=(new Random()).Next(1111,5555).ToString();
Console.WriteLine("User details saved to database.");
Notify(Contact,"Registred Successfully,Your UserID is:"+userID);
//Code
to generate random 4 digit T-pin
string
PIN=(new Random()).Next(5555,9999).ToString();
Notify(Contact, "Your PIN is " + PIN);
}
}
public class ContactDetail
{
public
string Email;
public
string MobNo;
}
}
class Program
{
static void Main(string[]
args)
{
User
usr = new User();
usr.Name = "satya";
usr.Age = 29;
usr.Contact.Email = "satya@test.com";
usr.Contact.MobNo = "997766553";
usr.Notify += new NotifyUser(SendEmail);
usr.Register();
Console.Read();
}
static void SendEmail(ContactDetail
objContact, string NotificationMsg)
{
string
email = objContact.Email;
//Add
your code to send NotificationMsg to the user email.
Console.WriteLine("email Sent to" + email);
}
}
Output:
Can we make the program better in a
industry standard way?
We
practically exposed an event and handled it. But it’s not a industry standard
way or recommended way.
So how can
we make it better?..just by using System.EventHandler delegate.
Show me the complete program?
namespace
RegistrationModule
{
public class User
{
public
string Name;
public
int Age;
public
ContactDetail Contact=new ContactDetail();
public event EventHandler<NotiFyEventArgs>
Notify;
public
void Register()
{
//code
to save the user details to the database
//
and generate userID
string
userID=(new Random()).Next(1111,5555).ToString();
Console.WriteLine("User details saved to database.");
NotiFyEventArgs args = new
NotiFyEventArgs();
args.Contact = Contact;
args.NotificationMsg = "Registred
Successfully,Your UserID is:" + userID;
Notify(null,args);
//Code
to generate random 4 digit T-pin
string
PIN=(new Random()).Next(5555,9999).ToString();
args.NotificationMsg = "Your
PIN is " + PIN;
Notify(null,args);
}
}
public class ContactDetail
{
public
string Email;
public
string MobNo;
}
public class NotiFyEventArgs : EventArgs
{
public ContactDetail Contact;
public string
NotificationMsg;
}
}
class Program
{
static void Main(string[]
args)
{
User
usr = new User();
usr.Name = "satya";
usr.Age = 29;
usr.Contact.Email = "satya@test.com";
usr.Contact.MobNo = "997766553";
usr.Notify += new EventHandler<NotiFyEventArgs>(SendSMS);
usr.Register();
Console.Read();
}
static void SendSMS(object
o,NotiFyEventArgs args)
{
string
MobNo = args.Contact.MobNo;
//Add
your code to send NotificationMsg to the user mobile number.
Console.WriteLine("SMS Sent to" + MobNo);
}
}
OutPut:

Are we done??
Yes almost, just one
more recommendation, use On before event .Say for example in our case we can
name our event as OnRegistration instead of Notify.But I have kept it Notify
just to keep the naming same, so that there will be less change between
programs.
I hope this article will be useful. Appreciate if you can by responding to this article.