The role of Delegates

By : |October 30, 2001 0



Sonali Gogate

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

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 —

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.

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 –

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

Delegates as static members

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 —

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)

No Comments so fars

Jump into a conversation

No Comments Yet!

You can be the one to start a conversation.