I was also confused as to how my approach should be. Should I write it in such a way that non-techies would also understand it ? Or should I aim at the developers who have atleast a general idea of what a class is? Although I would like to go the first way, there are atleast three reasons I am forced to go with the second option.
1)I dont think non-techies would like to dig deep into the .NET trenches irrespective of the way I present things.
2)Most of the people who read my blog are technical people.
3)I wouldnt be able to do justice to the real topic at hand, if I have to write so much explaining the context to the layman which is so painfully obvious to techies.
The title of this blog might have given a clue to what this blog is going to be. Its about programming with events. I just would like to assume that you would be knowing what an event is. If you dont, there aint much use reading the rest of this anyway.
Events are a convenience for modern programming. I will show here how to implement event handling mechanism in C#. Delegates are an integral part of the .NET framework and play a key role in the event handling mechanism. Put simply, delegates are type-safe function pointers.
Let us assume there is a Publisher class which raise an event and a Subscriber class is interested in that event.
using System;
class Publisher
{
private int _state = 0;
public delegate void StateChangeEventHandler(Object sender,EventArgs args);
public event StateChangeEventHandler StateChanged;
public int State
{
get
{
return _state;
}
set
{
_state = value;
if(StateChanged != null)
StateChanged(this,EventArgs.Empty);
}
}
}
In our Publisher class we have an event called StateChanged which will be raised when the State property changes. To raise the event we use this code :
StateChanged(this,new EventArgs());
But the problem is that if no objects have subscribed to this event, you will get a NullReferenceException. To prevent that we need a check :
if(StateChanged != null)
//raise event
Usually we would keep the above code in a separate method like:
private void OnStateChanged(EventArgs e)
{
if(StateChanged != null)
StateChanged(this,e);
}
For additional flexibility we can make this method protected virtual so that derived types can have some control over the firing of events.
protected virtual void OnStateChanged(EventArgs e)
{
if(StateChanged != null)
StateChanged(this,e);
}
Now our Publisher class will look like this :
using System;
class Publisher
{
private int _state = 0;
public delegate void StateChangeEventHandler(Object sender,EventArgs args);
public event StateChangeEventHandler StateChanged;
public int State
{
get
{
return _state;
}
set
{
_state = value;
OnStateChanged(EventArgs.Empty);
}
}
protected virtual void OnStateChanged(EventArgs e)
{
if(StateChanged != null)
StateChanged(this,e);
}
}//~end of Publisher class
Now that we know how to publish and raise events, we can look at how to setup a subscriber.
class Subscriber
{
public void Subscribe(Publisher pub)
{
pub.StateChanged += new Publisher.StateChangeEventHandler(pub_StateChanged);
}
public void UnSubscribe(Publisher pub)
{
pub.StateChanged -= new Publisher.StateChangeEventHandler(pub_StateChanged);
}
private void pub_StateChanged(Object sender,EventArgs args)
{
Console.WriteLine(sender.GetType().ToString() + “‘s State Changed !”);
}
}//~end of Subscriber class
We can have static events if we so prefer. If you subscribe to a static event, you will receive notifications from all instances of the Publisher class and if you unsubscribe you will recieve notifications from none. You dont need an instance of the Publisher class to subscribe to a static event. Note that nothing prevents the eventhandler function itself from being a static function.
As a point of interest, it should be mentioned that an event is implemented by a multicast delegate. To handle multiple subscribers it would internally maintain a list of subscribers.
If you didnt guess it till now, the event mechanism follows the Observer design pattern (see Design Patterns by the GoF).
P.S. Sorry about the formatting, I tried my best though
So my technical rants are just for my own benefit. If anyone else gets something useful out of these blogs, that would be a real pleasant bonus.
Man, you should explore what is known as “blog categories”.