Alarming Delegates (Advanced)

So here goes a post about c# delegates, which is considered to be one of the hardest concept in C#. So I've decided to show you a simple example which I guess will clear the concept of delegates for you.

Delegates are like function pointers in C++ and and broadly used as a callback function. Functions can be encapsulated using delegates. As you already know that C# is an event based programming language, you will be happy to know that behind the scene all events are basically delegates. So sooner or later you will find yourself learning delegates.

'Nuff said! Let's talk about the example which we are going to build. Our example is very simple one. All we are going to build is a simple console app, which will work like a clock. It will only count the seconds, so you can call it a second's clock. In this simple app you will have to set an alarm for an upcoming second. The app will continuously check the current second against the second set at compile time and will show an alarming message if the condition is matched.

Now let's talk about how we are going to build it using delegates. For simplicity let's create a Clock class first. For now the class only contains a single DateTime property named Alarm.


public class Clock
{
    public DateTime Alarm { get; set; }
}

We will use this auto property to set an alarm time in seconds in near future.

We all know that Class and Struct are some ways of creating user defined types. Likewise delegates can be used to define a type which can only encapsulate functions. Signature of a delegate type is more like a function declaration. To declare a delegate, you simply have to follow the signature given below,

access_modifier delegate_keyword reurn_type delegate_name(type parameter1,……);

So, let's go and create our own delegate as

public delegate void ClockAlarm(Clock clock, string name);

As you can see our newly created delegate, ClockAlarm can take a Clock object and a string as parameters and can return a void type. Everything is set.

So I successfully declared a delegate but there is no use of it. Let's go to our Main method in Program class and write some magical code. Let's start by creating an instance of our Clock class and assign a seconds value of a near future for the Alarm property.


var clock = new Clock();
clock.Alarm =  DateTime.Now.AddSeconds(5);

Now it's time to encapsulate a function with our ClockAlarm delegate. You may be thinking now that's ok so I have a delegate to which I can attach a function. But what will be the signature and definition of the attaching function? I know you are geek enough and figured out the attaching functions' signature. Yes you are right!!! its signature is same as our ClockAlarm delegate. If we try to attach a function whose signature mismatches with our ClockAlarm delegate signature, it will give you a compile time error.

Next let's create our attaching or subscribing function with definition as below


private static void Wakeup(Clock clock)
{
    while (true)
    {
        Thread.Sleep(1000);
        DateTime currentTime = DateTime.Now;     

        if (currentTime.Second == clock.Alarm.Second)
        {
            Console.WriteLine("Please wake up!!!!");
            break;
        }

        Console.WriteLine("Clock is ticking!!!");
    }
}

The code is very simple all we did is created a while loop which will first send the system to sleep for one second and wake it up. After that it will assign the current DateTime value to the currentTime variable. The if clause checks if the current second matches the Alarm property value which was passed in the function object. If the clause is true then it prints the message,

"Please wake up!!!!"
and breaks out of the loop otherwise it will continuously print,
"Clock is ticking!!!"

Now its time to create an instance of our delegate and then attach the subscribing function to it.


ClockAlarm clockAlarm;
clockAlarm = Wakeup;

Last of all we will have to invoke the delegate with the required parameters. To do that we will simply have to write

clockAlarm(clock, "Fiyaz");

So I guess you got the point. With the help of a delegate we are making a function subscribing to an event which is basically for now is simply an alarm notification. Now if you run the program you'll something like this,

We can attach more than one subscribing functions to our delegate which is a process of multicasting delegates. More about delegate multicasting in the next post.