Skip to content

Delegate

Jasper Zanjani edited this page Aug 21, 2020 · 2 revisions

Delegates are a functional programming feature in C# that facilitate loose coupling. Delegates can be used for messaging in .NET and especially to tie events to event handlers, but they are no longer used as much as Func<T,TResult> and Action<T>. Delegates take the form of a method signature using the delegate keyword.

Delegates can be understood as forming the structure of methods whose implementation has yet to be finalized, such as information forms which may evolve in appearance but always require the same information.

The simplest possible implementation of a delegate here uses a lambda:

  • A delegate is declared within the class where it is to be used, establishing the pattern of arguments
  • The delegate is instantiated within the body of the code similar to an object.
  • The instance is then called like a method.
using System;

namespace SimpleDelegate
{
  class Program
  {
    delegate void OnEvent();

    static void Main(string[] args)
    {
      OnEvent handler = () => Console.WriteLine("Implementing delegate");
      handler();
    }
  }
}

Typically, however, the method is not anymous but named:

using System;

namespace SimpleEvents
{
  class Program
  {
    delegate void OnEvent();

    static void Main(string[] args)
    {
      OnEvent handler = new OnEvent(DelegateImplementation);
      handler();
    }

    static void DelegateImplementation()
    {
      Console.WriteLine("Implementing delegate");
    }
  }
}
public delegate void InformationNeeded(int n, string s);

One or more methods implementing the delegate can be formulated. These do not reference the delegate in any way, shape, or form, except that their method signature matches that specified by the delegate. The variables used within the methods do not matter, only the data types:

// An initial, poor implementation:
void SimpleReport(int m, string t)
{
  Console.WriteLine($"int: {m}, string: {t}");
}

// An improved, later implementation:
void BetterReport(int m, string t)
{
  Console.WriteLine($"There are {m} items of type {t}");
}

Where the method is to be used, instead of calling the method directly, the delegate is instantiated like an object, but the name of the specific method that implements the delegate is passed as a parameter. The instantiated delegate can then be called, which passes the parameters to the method.

InformationNeeded form = new InformationNeeded(SimpleReport);
form(2, "kiwi");

This results in looser coupling because when changing implementation, only the parameter specifying the improved method needs to be ajusted, and the delegate ensures that the same pattern of parameters is enforced at compile-time.

InformationNeeded form = new InformationNeeded(BetterReport);
form(3, "jackfruit");
Clone this wiki locally