Delegates and events - audio blog
We will see about delegates and events in today's blog.
Delegates :
Delegates are very much similar to function pointers.
Everyone comfortable with function pointers ? I will explain function pointers briefly ( so that i would be clear about it !! )
Function pointers are variables(pointer variable) that points to address of a function. I don’t know why function pointer is seen as some advanced concept and not taught at schools/colleges. They are even simpler than other pointers since they are type safe !!
So coming back to delegates, Literally Delegate is a person who acts on behalf of some other person or group.
Technically, Delegates are variables pointing to some other function. We have the concept of delegate in C#. Java doesn't support delegates... however the function of delegates can be achieved using interfaces.
Ok, i know things are not so clear now.. let me explain with some code.( C# uses delegates ! )
public delegate int delegate_func(int x,int y);
Now we have declared a delegate type called delegate_func. What we can do next is create a variable of this type.
public delegate_func operate_func;
Now we have created a variable called operate_func of type delegate_func.
Of type delegate_func?? you must be confused ! Yes delegate_func is a type... it's unique in the sense it accepts functions which have return type int and has two parameters of type int.
Now suppose you have two functions,
int add(int x,int y)
{
return x+y;
}
int sub(int x,int y)
{
return x-y;
}
We can now assign the delegate variable some value... obviously that value is going to be a function(function address!)
In our example we can do,
operate_func=add; // or operate_func=sub
and then call add or sub functions as,
cout<<operate_func(3,2);
So,
operate_func=add;
cout<<operate_func(3,2)<<”\n”;
operate_func=sub;
cout<<operate_func(3,2);
The above piece of code will produce the following output,
5
1
Why do we use delegates??
There are lot of reasons.Since i'm new to delegates i will explain one very basic use.
Suppose you have a function which does a bunch of stuff and few things and again some bunch of stuff.You have copy pasted this function many times and everytime changed only the ‘few things’ part in middle.
A better way to implement this is to use a single function and pass these few lines of code which changes as argument. Wondering how?? write different functions having those different few lines of code. Assign which function is to be called during run time using a delegate. I hope you can understand what i mean !
delegate_func a,b,c;
a = new delegate_func(add);
b=new delegate_func(sub);
The above code is also correct !
Now comes another interesting thing about delegates,
you can actually,
c=a+b;
do this!
c(5,2);
will output ,
7
3
cool right?
In a similar way - (minus) sign can be used to remove a delegate from a list of delegates !
Did you notice that a delegate object encapsulates a function so that it can be called anonymously ?? In the above example we had operate_func encapsulating add , sub functions.
Delegates are ideally suited for event handling.. lets see more about events next.
Events:
Now read carefully.. this may be tricky!
A class has some clients or subscribers. Events are a way to allow these clients to add delegates to methods that should be called when some event occurs !
Events are actually declared using delegates.
Confusing? even am confused here ...
It’s iimpossible for me to explain about events and event handling without a code. So i use a standard code given in msdn ,
// events1.cs
using System;
namespace MyCollections
{
using System.Collections;
// A delegate type for hooking up change notifications.
public delegate void ChangedEventHandler(object sender, EventArgs e);
// A class that works just like ArrayList, but sends event
// notifications whenever the list changes.
public class ListWithChangedEvent: ArrayList
{
// An event that clients can use to be notified whenever the
// elements of the list change.
public event ChangedEventHandler Changed;
// Invoke the Changed event; called whenever list changes
protected virtual void OnChanged(EventArgs e)
{
if (Changed != null)
Changed(this, e);
}
// Override some of the methods that can change the list;
// invoke event after each
public override int Add(object value)
{
int i = base.Add(value);
OnChanged(EventArgs.Empty);
return i;
}
public override void Clear()
{
base.Clear();
OnChanged(EventArgs.Empty);
}
public override object this[int index]
{
set
{
base[index] = value;
OnChanged(EventArgs.Empty);
}
}
}
}
namespace TestEvents
{
using MyCollections;
class EventListener
{
private ListWithChangedEvent List;
public EventListener(ListWithChangedEvent list)
{
List = list;
// Add "ListChanged" to the Changed event on "List".
List.Changed += new ChangedEventHandler(ListChanged);
}
// This will be called whenever the list changes.
private void ListChanged(object sender, EventArgs e)
{
Console.WriteLine("This is called when the event fires.");
}
public void Detach()
{
// Detach the event and delete the list
List.Changed -= new ChangedEventHandler(ListChanged);
List = null;
}
}
class Test
{
// Test the ListWithChangedEvent class.
public static void Main()
{
// Create a new list.
ListWithChangedEvent list = new ListWithChangedEvent();
// Create a class that listens to the list's change event.
EventListener listener = new EventListener(list);
// Add and remove items from the list.
list.Add("item 1");
list.Clear();
listener.Detach();
}
}
Here we have extended ListWithChanged class from the standard List class.
ChangedEventhandler is a delegate !
Changed is an event .
Whenever required Changed event can be triggered.(see overridded functions)
We then create another class for listening purpose ... called EventListener
Here we connect the event Changed with some function having same prototype as the delegate ChangedEventHandler.
So what happens is whenever the Changed event is triggered this connected function in the EventListener class is called.
In main function,
we create an object for our Extended List class and then pass it to the constructor of Listener class.
I guess the code is self-explanatory and what i told above would just make it easier to understand Events !
Other points about events...
So why events when we have multicast delegates?
The problem with multicast delegates is that we(publishers) have to add the methods to delegates and subscribers have no control. On the other hand, if we pass the delegate to the subscriber it gives the subscriber full freedom to invoke other functions of the delegates. This is called encapsulation violation !! Events on the other hand (even if declared public) can be invoked only from the class which created it !! other classes can only subscribe or unsubscribe using += or -= operators (awesomeness !) . In a nutshell, Events cover delegates and provide encapsulation so that subscribers can only listen.
I think that’s enough said about delegates and events. Thanks for reading. See you in next blog !
Audio blog of delegates and events
Trained @ Sourcebits
We will see about delegates and events in today's blog.
Delegates :
Delegates are very much similar to function pointers.
Everyone comfortable with function pointers ? I will explain function pointers briefly ( so that i would be clear about it !! )
Function pointers are variables(pointer variable) that points to address of a function. I don’t know why function pointer is seen as some advanced concept and not taught at schools/colleges. They are even simpler than other pointers since they are type safe !!
So coming back to delegates, Literally Delegate is a person who acts on behalf of some other person or group.
Technically, Delegates are variables pointing to some other function. We have the concept of delegate in C#. Java doesn't support delegates... however the function of delegates can be achieved using interfaces.
Ok, i know things are not so clear now.. let me explain with some code.( C# uses delegates ! )
public delegate int delegate_func(int x,int y);
Now we have declared a delegate type called delegate_func. What we can do next is create a variable of this type.
public delegate_func operate_func;
Now we have created a variable called operate_func of type delegate_func.
Of type delegate_func?? you must be confused ! Yes delegate_func is a type... it's unique in the sense it accepts functions which have return type int and has two parameters of type int.
Now suppose you have two functions,
int add(int x,int y)
{
return x+y;
}
int sub(int x,int y)
{
return x-y;
}
We can now assign the delegate variable some value... obviously that value is going to be a function(function address!)
In our example we can do,
operate_func=add; // or operate_func=sub
and then call add or sub functions as,
cout<<operate_func(3,2);
So,
operate_func=add;
cout<<operate_func(3,2)<<”\n”;
operate_func=sub;
cout<<operate_func(3,2);
The above piece of code will produce the following output,
5
1
Why do we use delegates??
There are lot of reasons.Since i'm new to delegates i will explain one very basic use.
Suppose you have a function which does a bunch of stuff and few things and again some bunch of stuff.You have copy pasted this function many times and everytime changed only the ‘few things’ part in middle.
A better way to implement this is to use a single function and pass these few lines of code which changes as argument. Wondering how?? write different functions having those different few lines of code. Assign which function is to be called during run time using a delegate. I hope you can understand what i mean !
delegate_func a,b,c;
a = new delegate_func(add);
b=new delegate_func(sub);
The above code is also correct !
Now comes another interesting thing about delegates,
you can actually,
c=a+b;
do this!
c(5,2);
will output ,
7
3
cool right?
In a similar way - (minus) sign can be used to remove a delegate from a list of delegates !
Did you notice that a delegate object encapsulates a function so that it can be called anonymously ?? In the above example we had operate_func encapsulating add , sub functions.
Delegates are ideally suited for event handling.. lets see more about events next.
Events:
Now read carefully.. this may be tricky!
A class has some clients or subscribers. Events are a way to allow these clients to add delegates to methods that should be called when some event occurs !
Events are actually declared using delegates.
Confusing? even am confused here ...
It’s iimpossible for me to explain about events and event handling without a code. So i use a standard code given in msdn ,
// events1.cs
using System;
namespace MyCollections
{
using System.Collections;
// A delegate type for hooking up change notifications.
public delegate void ChangedEventHandler(object sender, EventArgs e);
// A class that works just like ArrayList, but sends event
// notifications whenever the list changes.
public class ListWithChangedEvent: ArrayList
{
// An event that clients can use to be notified whenever the
// elements of the list change.
public event ChangedEventHandler Changed;
// Invoke the Changed event; called whenever list changes
protected virtual void OnChanged(EventArgs e)
{
if (Changed != null)
Changed(this, e);
}
// Override some of the methods that can change the list;
// invoke event after each
public override int Add(object value)
{
int i = base.Add(value);
OnChanged(EventArgs.Empty);
return i;
}
public override void Clear()
{
base.Clear();
OnChanged(EventArgs.Empty);
}
public override object this[int index]
{
set
{
base[index] = value;
OnChanged(EventArgs.Empty);
}
}
}
}
namespace TestEvents
{
using MyCollections;
class EventListener
{
private ListWithChangedEvent List;
public EventListener(ListWithChangedEvent list)
{
List = list;
// Add "ListChanged" to the Changed event on "List".
List.Changed += new ChangedEventHandler(ListChanged);
}
// This will be called whenever the list changes.
private void ListChanged(object sender, EventArgs e)
{
Console.WriteLine("This is called when the event fires.");
}
public void Detach()
{
// Detach the event and delete the list
List.Changed -= new ChangedEventHandler(ListChanged);
List = null;
}
}
class Test
{
// Test the ListWithChangedEvent class.
public static void Main()
{
// Create a new list.
ListWithChangedEvent list = new ListWithChangedEvent();
// Create a class that listens to the list's change event.
EventListener listener = new EventListener(list);
// Add and remove items from the list.
list.Add("item 1");
list.Clear();
listener.Detach();
}
}
Here we have extended ListWithChanged class from the standard List class.
ChangedEventhandler is a delegate !
Changed is an event .
Whenever required Changed event can be triggered.(see overridded functions)
We then create another class for listening purpose ... called EventListener
Here we connect the event Changed with some function having same prototype as the delegate ChangedEventHandler.
So what happens is whenever the Changed event is triggered this connected function in the EventListener class is called.
In main function,
we create an object for our Extended List class and then pass it to the constructor of Listener class.
I guess the code is self-explanatory and what i told above would just make it easier to understand Events !
Other points about events...
- an event can have more than one subscribers !
- They are mostly used in GUI programs...
So why events when we have multicast delegates?
The problem with multicast delegates is that we(publishers) have to add the methods to delegates and subscribers have no control. On the other hand, if we pass the delegate to the subscriber it gives the subscriber full freedom to invoke other functions of the delegates. This is called encapsulation violation !! Events on the other hand (even if declared public) can be invoked only from the class which created it !! other classes can only subscribe or unsubscribe using += or -= operators (awesomeness !) . In a nutshell, Events cover delegates and provide encapsulation so that subscribers can only listen.
I think that’s enough said about delegates and events. Thanks for reading. See you in next blog !
Audio blog of delegates and events
Trained @ Sourcebits
Delegates could use some more of your explanations :D
ReplyDeleteWill explain more after working on it soon !
Delete