Delegates

A delegate is a type that enables you to store references to functions. Although this sounds quite involved, the mechanism is surprisingly simple.
The delegate declaration specifies a return type and parameter list. After defining a delegate, you can declare a variable with the type of that delegate. You can then initialize the variable as a reference to any function that has the same return type and parameter list as that delegate. Once you have done this, you can call that function by using the delegate variable as if it were a function.
 
When you have a variable that refers to a function, you can also perform other operations that would be otherwise impossible. For example, you can pass a delegate variable to a function as a parameter, and then that function can use the delegate to call whatever function it refers to, without knowing what function will be called until runtime.Following example demonstrate things.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        delegate double ProcessDelegate(double param1, double param2);
        static double Multiply(double param1, double param2)
        {
            return param1 * param2;
        }
        static double Divide(double param1, double param2)
        {
            return param1 / param2;
        }
        static void Main(string[] args)
        {
            ProcessDelegate process;
            Console.WriteLine("Enter 2 numbers separated with a comma");
            string input = Console.ReadLine();
            int commaPos = input.IndexOf(',');
            double param1 = Convert.ToDouble(input.Substring(0, commaPos));
            double param2 = Convert.ToDouble(input.Substring(commaPos + 1,
            input.Length - commaPos - 1));
            Console.WriteLine("Enter M to multiply or D to divide");
            input = Console.ReadLine();
            if (input == "M")
                process = new ProcessDelegate(Multiply);
            else
                process = new ProcessDelegate(Divide);
            Console.WriteLine("Result: {0}", process(param1, param2));
            Console.ReadKey();
        }
    }
}

This code defines a delegate ( ProcessDelegate ) whose return type and parameters match those of the two functions ( Multiply() and Divide() ). The delegate definition is as follows:

delegate double ProcessDelegate(double param1, double param2);

The delegate keyword specifies that the definition is for a delegate, rather than a function (the definition appears in the same place that a function definition might). Next, the definition specifies a double return value and two double parameters. The actual names used are arbitrary; you can call the delegate type and parameter names whatever you like. Here, we ’ ve used a delegate name of ProcessDelegate and double parameters called param1 and param2 . The code in Main() starts by declaring a variable using the new delegate type:

static void Main(string[] args)
{
ProcessDelegate process;

Next you have some fairly standard C# code that requests two numbers separated by a comma, and then places these numbers in two double variables:

Console.WriteLine("Enter 2 numbers separated with a comma");
string input = Console.ReadLine();
int commaPos = input.IndexOf(',');
double param1 = Convert.ToDouble(input.Substring(0, commaPos));
double param2 = Convert.ToDouble(input.Substring(commaPos + 1,
input.Length - commaPos - 1));

For demonstration purposes, no user input validation is included here. If this were ” real ” code, you ’ d spend much more time ensuring that you had valid values in the local param1 and param2 variables. Next, you ask the user to multiply or divide these numbers:

Console.WriteLine("Enter M to multiply or D to divide");
input = Console.ReadLine();

Based on the user ’ s choice, you initialize the process delegate variable:

if (input == "M")
    process = new ProcessDelegate(Multiply);
else
    process = new ProcessDelegate(Divide);

To assign a function reference to a delegate variable, you use slightly odd – looking syntax. Much like assigning array values, you must use the new keyword to create a new delegate. After this keyword, you specify the delegate type and supply a parameter referring to the function you want to use — namely, the Multiply() or Divide() function. This parameter doesn ’ t match the parameters of the delegate type or the target function; it is a syntax unique to delegate assignment. The parameter is simply the name of the function to use, without any parentheses.
 
Finally, call the chosen function using the delegate. The same syntax works here, regardless of which function the delegate refers to:

Console.WriteLine("Result: {0}", process(param1, param2));
Console.ReadKey();
}

Here, you treat the delegate variable as if it were a function name. Unlike a function, though, you can also perform additional operations on this variable, such as passing it to a function via a parameter, as shown in this simple example:

static void ExecuteFunction(ProcessDelegate process)
{
process(2.2, 3.3);
}

This means that you can control the behavior of functions by passing them function delegates, much like choosing a “ snap – in ” to use. For example, you might have a function that sorts a string array alphabetically. You can use several techniques to sort lists, with varying performance depending on the characteristics of the list being sorted. By using delegates, you can specify the function to use by passing a sorting algorithm function delegate to a sorting function.