Posts Tagged ‘delegates’
Understanding Delegates
Posted by fr3dr1k | Filed under C#
So one of the topics I have been telling myself to understand a bit better is delegates, and I think tonight I understand a bit more. Firstly a delegate can be described in simple terms as a type that references a method. So for instance you would have a class with a method that you would like to maybe re-use in another class without having implement it again. In this instance you might want to use a delegate. A delegate must have the same signature as the method it references, and you use the Delegate keyword for that. I created a very basic example to illustrate its use:
delegate string Del(string myString);
class Program
{
static void Main(string[] args)
{
Program p = new Program();
Del d = p.Myname;
d += p.MySurname;
Console.WriteLine(d("Fredrik"));
Console.WriteLine(d("Erasmus"));
}
string Myname(string myString)
{
return myString;
}
string MySurname(string myString)
{
return myString;
}
}
C# and delegates
Posted by fr3dr1k | Filed under C#
In C# there are four things most objects consist of:
- Properties (think yellow)
- Fields (think blue)
- Methods (think purple)
- Events (think a lightning bolt)
Events are implemented in C# through delegates. Think of a button on a web or windows form when you try and understand delegates. The button class will not know how other classes will handle its on_click event, so it exposes that event through a delegate. Essentially it’s saying, here is the event, I don’t know how you are going to handle it, but to handle it you must conform to my delegate’s signature.
The basic structure of creating events revolves around creating a class that inherits from EventArgs. You then create a class that will provide or handle the event. Within this class you create the delegate, and an instance of the delegate. You can then create classes that will use the delegate (subscribers / observers) by passing a method with the same signature as the delegate declaration to the event.
For the purposes of an example I’ll use a traffic light. In Jesse Liberty’s book Programming C# 5th Edition, he uses a clock as an example and on MSDN there is a sample that uses a fire extinguisher. Every example is event-driven. So, firstly you create a class that inherits from EventArgs:
public class TrafficEventArgs : EventArgs
{
public readonly int go;
public readonly int wait;
public readonly int stop;
public TrafficEventArgs(int go, int wait, int stop)
{
this.go = go;
this.wait = wait;
this.stop = stop;
}
}
Then you create a class that will handle the event:
public class TrafficLight
{
public delegate void TrafficLightHandler(object o, TrafficEventArgs e);
public event TrafficLightHandler TrafficHandled;
protected void OnTrafficLightChanged(TrafficEventArgs e)
{
if (TrafficHandled != null)
{
TrafficHandled(this, e);
}
}
public void Run()
{
for (int j = 0; j< 50 ; j++ )
{
Thread.Sleep(500);
for (int i = 0; i < 3; i++)
{
if (i == 0)
{
TrafficEventArgs trafficInfo = new TrafficEventArgs(0, 0, 1);
OnTrafficLightChanged(trafficInfo);
}
else if(i == 1)
{
TrafficEventArgs trafficInfo = new TrafficEventArgs(0, 1, 0);
OnTrafficLightChanged(trafficInfo);
}
else if (i == 2)
{
TrafficEventArgs trafficInfo = new TrafficEventArgs(1, 0, 0);
OnTrafficLightChanged(trafficInfo);
}
}
}
}
}
The event keyword that precedes the delegate instance is important because it prevents the delegate instance from being called directly, which is not what you really want. Also notice that you can check if any events have been fired by checking if the delegate instance is null or not. From Jesse Liberty's book I have added some code that updates the event and notifies the classes that subscribe to that event.
The next step is to create one or more classes that subscribe to those events. I have chosen to create two classes, Car and Pedestrian to illustrate the use of delegate. The example lacks a bit of logic with regards to traffic handling, because a pedestrian should obviously stop when a car can go, and vice verse. But it still serves the purpose of explaining how delegates, and more precisely events work. Here is the code:
public class Car
{
public void Subscribe(TrafficLight theTrafficLight)
{
theTrafficLight.TrafficHandled += new TrafficLight.TrafficLightHandler(TheCarHasArrived);
}
public void TheCarHasArrived(object o, TrafficEventArgs e)
{
if (e.stop == 1)
{
Console.WriteLine("The Car Has Arrived. It must stop.");
}
else if (e.go == 1)
{
Console.WriteLine("The Car Has Arrived. It may go.");
}
else if (e.wait == 1)
{
Console.WriteLine("The Car Has Arrived. It must wait.");
}
}
}
public class Pedestrian
{
public void Subscribe(TrafficLight theTrafficLight)
{
theTrafficLight.TrafficHandled += new TrafficLight.TrafficLightHandler(ThePedestrianHasArrived);
}
public void ThePedestrianHasArrived(object o, TrafficEventArgs e)
{
if (e.stop == 1)
{
Console.WriteLine("The Pedestrian Has Arrived. It must stop.");
}
else if (e.go == 1)
{
Console.WriteLine("The Pedestrian Has Arrived. It may go.");
}
else if (e.wait == 1)
{
Console.WriteLine("The Pedestrian Has Arrived. It must wait.");
}
}
}
You may be wondering why I am focusing on 'elementary' C# concepts, and my answer would be that for the last 4 and a half years a lot of my development effort has been pretty scattered (web dev, SEO, other IT-related topics). I somehow managed to focus on C# to an extent, but I find that it's not enough to just have knowledge, you need to understand as well. And my goal, objective, for 2009 is to become a proficient/expert C# developer. I want to put a lot of energy into understanding every aspect of the language, and the .NET framework (CLR), for that matter.
