Advertisment

The role of Delegates

author-image
CIOL Bureau
Updated On
New Update

Sonali Gogate

Advertisment

Delegates

Delegates are defined at runtime and refer only to single methods (not

classes). They serve 2 main purposes — callback and event handling.

Callback methods

Advertisment

Callback methods are used when you need to pass a function pointer to some

function so that it could call you back. Callback is used most often in the

following two manners —

Asynchronous processing:

You can use callback functions for asynchronous processing if the called code

is likely to take considerable amount of time to complete the request. This

would typically work as follows —

Advertisment

Client function makes a call and passes the call back method to the called

function. The called function starts a thread and returns immediately. When the

called function completes processing the request it calls the call back

function. The benefit in this is that the client function can continue its

processing, without having to wait on a potentially lengthy synchronous call.

Adding custom code to code path:

Callback can be used to allow the client to specify the method to call to do

some custom processing. So when the called function completes its processing, it

would then make a call to the callback function, which would do the custom

processing defined.

Advertisment

Here is how you define and use a delegate —

class myClass
{

}
class DefineDelegate
{
   static myClass<> myinstances;
   public delegate void EnumInstancesCallback(myClass mclass);
   public static void EnumInstances(EnumInstancesCallback callback)
   {
         foreach (myClass mclass in myinstances)
         {
             callback(mclass);
         }
   }
}

And to use it -

Advertisment
DefineDelegate.EnumInstancesCallback myCallback =
new DefineDelegate.EnumInstancesCallback(myinstancesCallback);
DefineDelegate.EnumInstances(myCallback);

Delegates as static members

Advertisment

So does the client have to instantiate a delegate every time it wants to use

one? Not necessarily. C# allows you to define as a static class member, the

method that will be used to create the delegate.

Here is how I would define a delegate as a static member in my class —

Advertisment
public static DefineDelegate.EnumInstancesCallback myCallback =
new DefineDelegate.EnumInstancesCallback(myinstancesCallback);

Defining events with delegates

In C#, a class publishes events it can "raise" and then any number

of classes can subscribe to these events. When any event is raised the runtime

takes care of informing all the classes subscribing to it of its occurrence. The

method that gets called as a result of an event being raised is defined using

delegates.

Delegates to be defined for the purpose of event handling have to follow the

following rules —

  1. It must be defined as taking two parameters
  2. These parameters represent (1)the object that raises the event (the

    publisher of the event) and (2) an event information object.
  3. The event information object must be derived from EventArgs class.

And here is an example of defining and raising an event —

using System;

class ChangeEventArgs : EventArgs
{
   public ChangeEventArgs(string locale, int change)
   {
        this.locale = locale;
        this.change = change;
   }

   string locale;
   public string locale
   {
       get
       {
           return locale;
       }
   }
   int change;
   public int Change
   {
       get
       {
           return change;
       }
   }
}

class CngManager
{
    public delegate void ChangeEventHandler(object source, ChangeEventArgs e);
    public event ChangeEventHandler OnChangeHandler;

    public void UpdateCng(string locale, int change)
    {
ChangeEventArgs e = new ChangeEventArgs(locale, change);
if (OnChangeHandler != null)
OnChangeHandler(this, e);
}
}
class CngWatcher
{
   CngManager cngManager;

   public CngWatcher(CngManager cngManager)
   {
       this.cngManager = cngManager;
       cngManager.OnChangeHandler += new
CngManager.ChangeEventHandler(OnChange);
    }
    void OnChange(object source, ChangeEventArgs e)
    {
       int change = e.Change;
       Console.WriteLine("Part '{0}' was changed by {1} units",
           e.locale, Math.Abs(e.Change));
    }
}

class Events1App
{
    public static void Main()
    {
        CngManager cngManager = new CngManager();

        CngWatcher cngyWatch = new CngWatcher(CngManager);

        cngManager.UpdateCng("111 006 116", -2);
        cngManager.UpdateCng("111 005 383", 5);
    }
}

(The author is a technical evangelist at Microsoft India)

tech-news