Delegates in C#

  • A delegate is a type that represents references to methods with a particular parameter list and return type. When you instantiate a delegate, you can associate its instance with any method with a compatible signature and return type. You can invoke or call the method through the delegate instance.
  • Delegates are used to pass methods as arguments to other methods. Event handlers are nothing more than methods that are invoked through delegates. 
  • Delegates can be used to define callback methods.
  • Delegates can be chained together; multiple methods can be called on a single event.

There are three types of delegates that can be used in C#.

  1. Single Delegate
  2. Multicast Delegate
  3. Generic Delegate

Single Delegate

Single delegate can be used to invoke a single method.

// Declare a delegate
delegate double CalculateSimpleInterest(double p, double t, double r);
static CalculateSimpleInterest SI = getTotalInterest;

static double getTotalInterest(double p, double t, double r)
{
return (p * t * r) / 100;
}

double totalInterest;
//Method I : Invocation of simple delegate by using Invoke keyword
totalInterest = SI.Invoke(120, 1, 3.25);

//Method II : Invocation of simple delegate by passing method name CalculateSimpleInterest D = new CalculateSimpleInterest(getTotalInterest);
totalInterest = D(120, 1, 3.25);

Multicast Delegate

can be used to invoke multiple methods. The delegate instance can do multicasting (adding new method on existing delegate instance) using + operator and โ€“ operator can be used to remove a method from a delegate instance. All methods will invoke in sequence as they are assigned.

// Declare a delegate
delegate double CalculateSimpleInterest(double para1, double para2, double para3);
static CalculateSimpleInterest dObjSI = getTotalInterest;

static double getTotalInterest(double p, double t, double r)
{
return (p * t * r) / 100;
}
static double getInterestRatePerYear(double SI, double p, double t)
{
      return (SI * 100) / (p * t);
}
static double getInterestTimeSpan(double SI, double p, double r)
{
      return (SI * 100) / (p * r);
}

double SI;
//Calculating simple interest
SI = dObjSI.Invoke(120, 1, 3.25);
//using multicast delegate by invoking method getInterestRatePerYear()
dObjSI += new CalculateSimpleInterest(getInterestRatePerYear);
double Rate = dObjSI.Invoke(SI, 120, 1);

//using multicast delegate by invoking method getInterestTimeSpan()
dObjSI += new CalculateSimpleInterest(getInterestTimeSpan);
double TimeSpan = dObjSI.Invoke(SI, 120, 3.25);

Generic Delegate

  • donโ€™t require to define the delegate instance in order to invoke the methods. There are three types of generic delegates.
  • was introduced in .Net 3.5

1) Func
2) Action
3) Predicate

Action Delegate Type
  • The generic Action delegate represents a method that returns void. Different versions of Action take between 0 and 18 input parameters.
  • The action delegate that takes two arguments.
  • public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2)
Func Delegate Type
  • Func in short is parameterized delegate.
  • The generic Func delegate represents a method that returns a value.
  • Func handles many arguments.
  • It provides a way to store anonymous methods in a generalized and simple way.
// Create a Func instance that has one parameter and one return value.
// ... Parameter is an integer, result value is a string.
   Func<int, string> func1 = (x) => string.Format("string = {0}", x);

// Func instance with two parameters and one result.
// ... Receives bool and int, returns string.
   Func<bool, int, string> func2 = (b, x) =>
   string.Format("string = {0} and {1}", b, x);
            
// Func instance that has no parameters and one result value.
   Func<double> func3 = () => Math.PI / 2;

// Call the Invoke instance method on the anonymous functions.
   Console.WriteLine(func1.Invoke(5));
   Console.WriteLine(func2.Invoke(true, 10));
   Console.WriteLine(func3.Invoke());