Oude artikelen van mijzelf: Introduction to delegates


Weer een, waar volgens mijn stats nog steeds hits op komen. Deze lap tekst heb ik in 2005/2006 geschreven over delegation en events. De code voorbeelden zijn in C# .Net (geschreven op .Net framework 1.1). Blijkbaar linkt een of ander forum nog steeds naar dit artikel. Vandaar dat ik hem heb opgezocht in de “Way Back Machine” en hier heb geplaatst.

Delegation and Events

I never really understood how to delegates worked, until I received a very basic and simple explanation of someone. I’ll try to explain it to you by creating a light bulb and switch. In real life, when you flip a switch the light goes on or off. In the basic setting, you need three objects, the light bulb, switch and a wire. The light bulb and switch are connected by the wire.

What is a delegate?

Well, basically a delegate can call a method of a class (ClassA) on the request of another class (ClassB), while ClassB doesn’t know which method is called. The delegate stores a pointer to the method of ClassA and is called by ClassB.

In our example, the wire is the delegate. It transfers the signal from the switch to the light bulb.

Creating the delegate : Wire

The delegate in this example will act as the wire between the switch and light bulb.

   1:      public delegate void Wire(bool b);

Creating the classes : the light bulb

The light bulb class contains a state property, the light bulb can be on or off and it contains a counter. When the light is turned on and off 9 times or more, the light bulb will break.

   1:      class LightBulb
   2:      {
   3:          private bool _state;
   4:          private int flipCount = 0;
   5:          public bool State
   6:          {
   7:              get {return State;}
   8:              set {this._state = value;}
   9:          }
  10:          public void turnOnOff(bool newState)
  11:          {
  12:              this._state = newState;
  13:              flipCount++;
  14:              if(flipCount<10)
  15:                  Console.WriteLine("The light is {0}", (_state)?"ON":"OFF");
  16:              else
  17:                  Console.WriteLine("You've broken the light!!");
  18:          }
  19:      }

Creating the classes : the switch

Well, the switch contains a method, called flipSwitch. This changes the state of the switch to on or off, and raises an event called “onflipSwitch”. The switch will raise an event called onflipSwitch and uses the delegate Wire. If the switch is flipped 14 times or more, the switch breaks.

   1:      class Switch
   2:      {
   3:          private bool _state = false;
   4:          private int _flipCount = 0;
   5:          public event Wire onflipSwitch;
   7:          public void flipSwitch()
   8:          {
   9:              _state = !_state;
  10:              _flipCount++;
  11:              if(_flipCount < 15)
  12:              {
  13:                  OnSwitchFlipped(_state);
  14:              }
  15:              else
  16:              {
  17:                  Console.WriteLine("You've broken the switch!!");
  18:              }
  19:          }
  21:          protected virtual void OnSwitchFlipped(bool state)
  22:          {
  23:              //Call delegate
  24:              if (onflipSwitch != null)
  25:                  onflipSwitch(state);
  26:          }
  27:      }

The trick of using events is to create an object of the type “Wire” (or your delegate) and add the keyword event. If the event is triggered (from the method “OnSwitchFlipped”) the delegate calls any methods subscribed to the delegate.

   1:      public event Wire onflipSwitch;

Creating the classes : The program

In this example a console application is created to show the workings of delegates and events.

   1:      class Program
   2:      {
   3:          [STAThread]
   4:          static void Main(string[] args)
   5:          {
   6:              LightBulb lb = new LightBulb();
   7:              Switch sw = new Switch();
   8:              sw.onflipSwitch += new Wire(lb.turnOnOff);
  10:              Console.WriteLine("Currently it is very dark in here");
  11:              Console.WriteLine("Press [enter] to flip the switch:");
  12:              while(Console.ReadLine().IndexOf("x") == -1)
  13:                  sw.flipSwitch();
  15:          }
  16:      }

In the Main method, two objects are created (one for the light bulb and one for the switch. If the switch is flipped the light bulb has to turn on or off. This is done by the delegate. See line 8. The rest of the code is a (very) simple user interface to flip the switch.

When/Where to use events/delegates?

Well, delegates are used when you don’t know which methods should be called when an event happens. Look at the webcontrols for instance. The linkbutton control doesn’t know which method(s) should be triggered when the button is clicked. The button contains an event called “Clicked” which can be subscribed to using the System.EventHandler delegate.