Search This Blog

Tuesday, June 25, 2013

Delegates

Delegates in terms of C language is  pointer to function.
Firstly I will try to explain what does this mean.

Pointer to Function
 In the following example we define one  function pointer named pt2Function.
This point to function, which take three int parameters and return an int
// define a function pointer and initialize to NULL
int (*pt2Function)(int, int, int) = NULL;  
// assign an address to the function pointer
int Fun1  (int a, int b, int c){    return a+b+c; }
int Fun2 (int a, int b, int  c)const{ return a-b+c; }
pt2Function = &Fun1;    // correct assignment using address operator
if(pt2Function >0){                           // check if initialized
   if(pt2Function == &Fun1)
      printf("Pointer points to Fun1\n"); }
else
   printf("Pointer not initialized!!\n");
// calling a function using a function pointer
int result = (*pt2Function) (12, 3, 5);  
Now  we will see :How to Pass a Function Pointer as an Argument
//  How to Pass a Function Pointer
//  is a pointer to a function which returns an int and takes three int
void PassPtr(int (*pt2Func)(int, int, int))
{
   int result = (*pt2Func)(12, 3, 6);     // call using function pointer
  
}
 and in some other point we execute this function
.....
PassPtr(&Fun1);
.....
and at the end we will see:How to Return a Function Pointer as function's return value
//  How to Return a Function Pointer
int (*GetPtr1(int f1))(int, int,int)
{
   if(f1==0)
      return &Fun2;
   else
      return &Fun1;
}
and in some other point inside of some function
// define a function pointer and initialize it to NULL
   int (*pt2Function)(int, int, int) = NULL;
pt2Function=GetPtr1(1);   // get function pointer from function 'GetPtr1'
int result = (*pt2Function) (12, 3, 5);    // call function using the pointer
Now we can go on with delegates.
Delegates
Generally speaking we can divide delegates in two types:Simple and multicast delegate.


Below is the syntax for declaring a delegate:
 delegate  DelegateName();
In the above Syntax:-
Scope: It is access specification like public, private etc.,
delegate: keyword
returntype: Function return type
DelegateName: Name of the delegate.
Parameters : Function parameter names with types.
Example
public delegate void GetFinalMulticastDelegate(Parammeter Parammeters);
I will start with the Simple type.
We have the follwing 3 classes:Delegate,Utilitty and Parameters

namespace Delegates
{
    class Delegate
    {
         // Delegate 
  public delegate string GetFinalDelegate(Parammeter[] Parammeters);

  // Other member variables
  private Parammeter[] Parammeters;
  private string PropertyName;

  // Constructor 
        public Delegate(string prop_name, params Parammeter[] parammeters)
  {
   //Initialize 
            Parammeters = new Parammeter[parammeters.Length];
            for (int i = 0; i < parammeters.Length; i++)
                Parammeters[i] = parammeters[i];

   // Initialize other member variables
            PropertyName = prop_name;
  }

  //Function that delegates 
        public string Calculate_Total(GetFinalDelegate delegateRef)
  {
            return delegateRef(Parammeters);
  }

  //
        public void DisplayParammeters()
  {
            foreach (Parammeter parammeter in Parammeters)
                Console.WriteLine(parammeter);
  }

    }
}
namespace Delegates
{
    class Utility
    {
        public static string Method1(Parammeter[] Parammeters)
        {
            string result="";
            foreach (Parammeter parammeter in Parammeters)
                result = result + parammeter.param1;
            return result;
        }

       
        public static string Method2(Parammeter[] Parammeters)
        {
            string result="";
            foreach (Parammeter parammeter in Parammeters)
                result = result + parammeter.param2;
            return result;
        }
    }
}

namespace Delegates
{
    class Parammeter
    {
        public string param1;
  public string param2;
  

  // 
        public Parammeter(string par1, string par2)
  {
            param1 = par1;
            param2 = par2;
   
  }

  //
  public override string ToString()
  {
            return string.Format("{0} - {1}", param1, param2);
  }

    }
}
At the end in some button event we have the following:

 private void button1_Click(object sender, EventArgs e)
        {
            Parammeter param1 = new Parammeter(" 1", " that");
            Parammeter param2 = new Parammeter(" 2", " is");
            Parammeter param3 = new Parammeter(" 3", " the");
            Parammeter param4 = new Parammeter(" 4", " delegate");

            
            Delegate Dlg = new Delegate("Greg", param1, param2, param3, param4);
            Dlg.DisplayParammeters();

            // Create the Delegates of same type pointing to different function
            Delegate.GetFinalDelegate FirstMethodResult = new Delegate.GetFinalDelegate(Utility.Method1);
            Delegate.GetFinalDelegate SecondMethodResult = new Delegate.GetFinalDelegate(Utility.Method2);

           
            string FinalResult;
            FinalResult = Dlg.Calculate_Total(FirstMethodResult) + Dlg.Calculate_Total(SecondMethodResult);
            label1.Text="Final Result  : " + FinalResult;
           
        }

Is very important to understand that the compiler generates some internal wrapper class with the name  GetFinalDelegate.That is the point!! Using  ildasm tool we can see this class.In Utility class methods must have the same signature as delegate GetFinalDelegate declared in Delegate Class.
Multicast Delegates.

We have the follwing 3 classes: DelegateMulticast,UtilityMulticast and Parameters
namespace Delegates
{
    class DelegateMulticast
    {
        public delegate void GetFinalMulticastDelegate(Parammeter Parammeters);

  // Other member variables
  private Parammeter[] Parammeters;
  private string PropertyName;

  //002_3: Constructor 
        public DelegateMulticast(string prop_name, params Parammeter[] parammeters)
  {
   //Initialize 
            Parammeters = new Parammeter[parammeters.Length];
            for (int i = 0; i < parammeters.Length; i++)
                Parammeters[i] = parammeters[i];

   // Initialize other member variables
            PropertyName = prop_name;
  }

  //Function that delegates 
        public void ProcessDlg(GetFinalMulticastDelegate delegateRef, Parammeter parammeters)
  {
             delegateRef(parammeters);
  }

  //002_5: Diaplay all Staffs
        public void DisplayParammeters()
  {
            foreach (Parammeter parammeter in Parammeters)
                Console.WriteLine(parammeter);
  }

    }
}

namespace Delegates
{
    class UtilityMulticast
    {
        public static void Method1(Parammeter Parammeters)
        {
            
        }
        public static void Method2(Parammeter Parammeters)
        {

        }
        public static void Method3(Parammeter Parammeters)
        {

        }
        public static void Method4(Parammeter Parammeters)
        {

        }
        public static void Method5(Parammeter Parammeters)
        {

        }


       
    }
}

At the end in some button event we have the following:

 private void button2_Click(object sender, EventArgs e)
        {
            Parammeter param1 = new Parammeter(" 1", " that");
            Parammeter param2 = new Parammeter(" 2", " is");
            Parammeter param3 = new Parammeter(" 3", " the");
            Parammeter param4 = new Parammeter(" 4", " delegate");

            //Client 002: Create Organization
            DelegateMulticast Dlg = new DelegateMulticast("Greg", param1, param2, param3, param4);
            Dlg.DisplayParammeters();
            DelegateMulticast.GetFinalMulticastDelegate Process;
            DelegateMulticast.GetFinalMulticastDelegate Process1 = new DelegateMulticast.GetFinalMulticastDelegate(UtilityMulticast.Method1);
            DelegateMulticast.GetFinalMulticastDelegate Process2 = new DelegateMulticast.GetFinalMulticastDelegate(UtilityMulticast.Method2);
            DelegateMulticast.GetFinalMulticastDelegate Process3 = new DelegateMulticast.GetFinalMulticastDelegate(UtilityMulticast.Method3);
            DelegateMulticast.GetFinalMulticastDelegate Process4 = new DelegateMulticast.GetFinalMulticastDelegate(UtilityMulticast.Method4);
            DelegateMulticast.GetFinalMulticastDelegate Process5 = new DelegateMulticast.GetFinalMulticastDelegate(UtilityMulticast.Method5);

            Process = Process1 + Process2 + Process3;
            Dlg.ProcessDlg(Process, param1);

            Process -= Process1 ;
            Process += Process2;
            Process += Process3;
            Dlg.ProcessDlg(Process, param1);
        }
    }

The difference between multicast and simple type delegate is that the retyrn type in multicast delegate must be void.
Also,as we can see ,we can add or remove instancew of delegate with += and -= operators.
            Process -= Process1 ;
            Process += Process2;
            Process += Process3;
            Dlg.ProcessDlg(Process, param1);

 At the end of this long story , i would like to ask the reader if it is possible to recognize in code where exactly is applied  the ''pointer to function"

No comments:

Post a Comment

Blog Archive

About Me

An seasoned developer, architect and with some Team Leading exposure, offering full project life cycle experiences within multi cultural, multi National environments and within differing business streams and all primarily on a .Net platform.