Tuesday, September 14, 2004









Delegates


Delegates are data types in the .NET framework that reference a method with a specific signature. Delegates are used to execute a method on a class via the created type. The ThreadStart type is an example of a delegate, in this case the ThreadStart delegate references a method that has an empty parameter list. You can create a ThreadStart delegate as follows:

  ThreadStart ts = new ThreadStart(DelegateFunction);
  Thread t = new Thread(ts);
  t.Start(); //start the thread
  
  for (int i = 0; i < 1000; i++)
   t.Sleep(5);
   
  


The ThreadStart class takes a reference to a method that cannot have any input parameters. The DelegateFunction is defined as:

  public void DelegateFunction()
  {
   // Do something...
  }
  


The DelegateFunction is executed when the Thread.Start function is run. In this case, the ThreadStart delegate wraps the method call, so that the method can be called via a type instance. Delegates are used for callback functions, events and as an implicit interface contract. A delegate can reference a function that takes parameters:

 public delegate string FunctionPointer(int foo, string bar);
 
 public FunctionPointer fpi; 
 fpi = new FunctionPointer(Function);
 


The Function declaration loooks like this:

 string Function(int foo, string bar)
 {
  string temp = "";

  for (int i = 0; i < foo; i++)
   temp += bar;
 
  return temp;
 }
 
The same delegate can point to another function with the same signature

 string AnotherFunction(int foo, string bar)
 {
  string temp = "AnotherFunction";

  for (int i = 0; i < foo; i++)
   temp += bar;

  return temp;
 }
 


The following is a sample console application that demonstrates delegates. In Main(), the source class and each sink class is created. The source class is the class that will call the function in the sink class via the delegate reference. Each sink class contains a method called Callback that will be called by the source class. To hook up the Callback method in the sink class to the delegate in the source class, a reference to the delegate is created and the name of the callback function in the sink class is passed as a parameter to the delegate reference constructor:

 using System;
 
 namespace Delegate
 {
  class Class1
  {
   [STAThread]
   static void Main(string[] args)
   {
    SourceClass sc = new SourceClass();
    SinkAClass sac = new SinkAClass();
    SinkBClass sbc = new SinkBClass();
 
    // Hook up the function and execute
    sc.fp = new SourceClass.FunctionPointer(sac.Callback);
    sc.DoSomething();
 
    // Hook up a new sink
    sc.fp = new SourceClass.FunctionPointer(sbc.Callback);
    sc.DoSomething();
   }
  }
 
  public class SourceClass
  {
   public delegate void FunctionPointer(int arg1, string arg2);
   public FunctionPointer fp;
 
   public void DoSomething()
   {
    // call the function pointed to by fp;
    fp(3, this.ToString());
   }
  }
 
  public class SinkAClass
  {
   public void Callback(int arg1, string arg2)
   {
    Console.WriteLine("{0} Callback method was called with arguments: {1}, {2}", this.ToString(), arg1.ToString(), arg2);
   }
  }
 
  public class SinkBClass
  {
   public void Callback(int arg1, string arg2)
   {
    Console.WriteLine("{0} Callback method was called with arguments: {1}, {2}", this.ToString(), arg1.ToString(), arg2);
   }
  }
 }







Comments: Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?