Saturday, February 12, 2011

Implementing Events and Delegates in C#





Events and Delegates

If you are a C# progarmmer, you might have read a lot of about Events and delegates. Before reading this article you must read the previous article "The Observer Design Pattern and Events and delegates in C#" .
Here I am presenting some C# code which clearly shows how events and delegates works !!

In this sample we have a clock class which acts as the publisher and two other classes  DisplayClock and TimeLogEntry which acts as subscribers. Both these classes registered with the publishers SecondChanged event. On each second changed , the subscribers will be notified.

Here is the code


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Delegate_Event_Ex
{
    // Clock class is the publisher , who triggers the event
    public class Clock
    {
        public delegate void SecondChangeHandler(object clock, TimeInfoEventArgs timeinformation);
        public event SecondChangeHandler SecondChanged;
        int hour;
        int minute;
        int second;
        public void Start()
        {
            while (true)
            {
                Thread.Sleep(100);
                DateTime dt = DateTime.Now;
                if (dt.Second != second)
                {
                    TimeInfoEventArgs timeArgs = new TimeInfoEventArgs(dt.Hour, dt.Minute, dt.Second);
                    if (SecondChanged != null)
                    {
                        SecondChanged(this, timeArgs);
                    }
                }
                this.hour = dt.Hour;
                this.minute = dt.Minute;
                this.second = dt.Second;
            }
        }

    }
    public class TimeInfoEventArgs : EventArgs
    {
       public int hour;
       public int minute;
       public int second;
        public TimeInfoEventArgs(int h, int m, int s)
        {
            this.hour = h;
            this.minute = m;
            this.second = s;
        }
    }
    //DisplayClock class is one of the Subscribers,who is responding to the event
    public class DisplayClock
    {
        public void Subscribe(Clock theClock)
        {
           // theClock.SecondChanged += new Clock.SecondChangeHandler(TimeHasChanged);
            theClock.SecondChanged += delegate(object theClock1, TimeInfoEventArgs ti)
            {
                Console.WriteLine("Calling Anonymous-Current Time: {0}:{1}:{2}",
                  ti.hour.ToString(), ti.minute.ToString(), ti.second.ToString());
            };
        }
        public void TimeHasChanged(object theClock, TimeInfoEventArgs ti)
        {
            Console.WriteLine("Current Time: {0}:{1}:{2}",
             ti.hour.ToString(), ti.minute.ToString(), ti.second.ToString());
        }
    }
    //TimeLogEntry Class is one of the Subscribers,who is responding to the event
    public class TimeLogEntry
    {
        public void Subscribe(Clock theClock)
        {
            theClock.SecondChanged += new Clock.SecondChangeHandler(LogEntry);
            theClock.SecondChanged +=
                                (aClock, ti) =>
                                {
                                    Console.WriteLine("Calling Lambda Expression-Current Time: {0}:{1}:{2}",
                                                       ti.hour.ToString(),
                                                       ti.minute.ToString(),
                                                       ti.second.ToString());
                                };
        }
        public void LogEntry(object theClock, TimeInfoEventArgs ti)
        {
            Console.WriteLine("Writing Log - Current Time: {0}:{1}:{2}",
            ti.hour.ToString(), ti.minute.ToString(), ti.second.ToString());
        }
    }
    public class MyTester
    {
        public void Run()
        {
            Clock clock = new Clock();
            DisplayClock dc = new DisplayClock();
            dc.Subscribe(clock);
            TimeLogEntry tle = new TimeLogEntry();
            tle.Subscribe(clock);
            //Console.WriteLine("Calling the method directly!");
            //System.DateTime dt = System.DateTime.Now.AddHours(2);
            //TimeInfoEventArgs timeInformation =
            //    new TimeInfoEventArgs(dt.Hour, dt.Minute, dt.Second);
            //clock.SecondChanged(clock, timeInformation);
            clock.Start();
        }
        
        
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyTester tester = new MyTester();
            tester.Run();
        }
    }
}

The output will be like this ( click on the Image to view large)


No comments:

Post a Comment