A colleague of mine asked me today about adding custom eventhandlers to a class. I explained the whole process to him and ended up doing a demo on how to accomplish this task. After a we were done talking it dawned to me that I haven't had the chance to blog code in weeks I think its a good time to show something that is pretty helpful when you understand how to use it.
I don’t have enough time to explain what events are so I’ll just give you a link to a great article in C# Help written by Sanju that details how events work in C#[link].
The first thing I did when my colleague came to my desk was to think of a good example on how to wire custom events to an existing class. After a few seconds of thinkering, I realized that a good candidate is the Stack class. A Stack is a data structure in which new elements are added to and removed from the top of the structure. A stack is characterized by last-in, first-out (LIFO) behavior[link]. Microsoft .NET has an implementation of the Stack class that you can readily used(instead of writting your own version). One of the things I didn't like about the Stack class is that it doesn't have an eventhandler for Push and Pop. This is necessary if you wanted to hook to those methods whenever a Push or Pop action initiated to your Stack.
Running with my idea, I decided to right a custom class called CustomStack to demonstrate how easily you can add custom events to classes. Below is the class that demonstrates how i was able to achieve my solution.
using System;
using System.Collections;
namespace KeithRull.WorkingWithStacks
{
class Program
{
static void Main(string[] args)
{
CustomStack s = new CustomStack();
//Add items to our list
s.Push("Keith");
s.Push("Charissa");
s.Push("Benilda");
s.Push("Orlando");
s.Push("Ria");
s.Push("Ivy");
s.Push("Bienvenido");
s.Push("Renz");
ShowStackItemCount(s);
//Remove two items from the Stack
s.Pop();
s.Pop();
ShowStackItemCount(s);
//Add 3 items to our list
s.Push("Joshua");
s.Push("Bethel");
s.Push("Lesther");
ShowStackItemCount(s);
//Pop 7 items out of our stack
s.Pop();
s.Pop();
s.Pop();
s.Pop();
s.Pop();
s.Pop();
s.Pop();
ShowStackItemCount(s);
//Show the contents of our Stack
ShowContentsOfStack(s);
Console.ReadLine();
}
static void ShowContentsOfStack(CustomStack s)
{
foreach (object o in s)
{
Console.WriteLine(o.ToString());
}
}
static void ShowStackItemCount(CustomStack s)
{
Console.WriteLine(s.Count);
}
}
class CustomStack : Stack
{
/// <summary>
/// Our event handler for the Push event
/// </summary>
/// <param name="o">the item to pushed to the stack</param>
public delegate void StackPushEventHandler(object o);
/// <summary>
/// Our event handler for the Pop event
/// </summary>
/// <param name="o">the item to be popped from our stack</param>
/// <returns>the popped item</returns>
public delegate object StackPopEventHandler(object o);
/// <summary>
/// The event for our Push
/// </summary>
public event StackPushEventHandler OnPush = new StackPushEventHandler(CustomStack_OnPush);
/// <summary>
/// The event for our Pop
/// </summary>
public event StackPopEventHandler OnPop = new StackPopEventHandler(CustomStack_OnPop);
public CustomStack()
: base()
{
}
/// <summary>
/// Overriden Push method
/// </summary>
/// <param name="obj">the object to be added to our stack</param>
public override void Push(object obj)
{
base.Push(obj);
//trigger the push event
OnPush(obj);
}
/// <summary>
/// Overriden Pop method
/// </summary>
/// <returns>The object to be 'popped'</returns>
public override object Pop()
{
//trigger to pop event and return the popped item
return OnPop(base.Pop());
}
/// <summary>
/// A method that is called when a Push action is done to the stack
/// </summary>
/// <param name="o">The object to add to our stack</param>
public static void CustomStack_OnPush(object o)
{
Console.WriteLine("Pushed: " + o.ToString());
}
/// <summary>
/// A method that is called when we Pop an item from our stack
/// </summary>
/// <param name="o">The object to be removed from our stack</param>
public static object CustomStack_OnPop(object o)
{
Console.WriteLine("Poped: " + o.ToString());
return o;
}
}
}
The result of the program above is listed below
Pushed: Keith
Pushed: Charissa
Pushed: Benilda
Pushed: Orlando
Pushed: Ria
Pushed: Ivy
Pushed: Bienvenid
Pushed: Renz
8
Poped: Renz
Poped: Bienvenido
6
Pushed: Joshua
Pushed: Bethel
Pushed: Lesther
9
Poped: Lesther
Poped: Bethel
Poped: Joshua
Poped: Ivy
Poped: Ria
Poped: Orlando
Poped: Benilda
2
Charissa
Keith
Nothing fancy, just pure code. In the end my co-worker loved the solution and I think he's implementing it now as I am writing this entry. Sweet.