C# Delegates - Introduction, Implementation and Chaining

December 30, 2017

If you have been developing applications with C#, then you must have encountered a concept named delegates. Delegates in C# can be referred as a pointer to methods.
Instead of calling a method directly with its name, we call the method with its reference. They can be used for events and callbacks.

A Direct method call would look like:

FindSquare(5) // to get the square of a number
or, Factorial(5); //to find factorial of a number

how a c# function call works


A delegate call (pseudocode) would look something like:


delegate numberChanger = FindSquare->Reference


where numberChanger is the name is the delegate that holds the reference to the function.



Implementing a simple numberChanger delegate

Consider the following method:
int FindSquare( int number )
{
    return (number*number);
}

To create a delegate, we need to create a new delegate object using the new operator.

The syntax for delegate declaration is:

delegate <return-type> <delegate-name> (<parameters>)

The actual implementation will look like:

Step 1: Declaring the delegate
delegate int ModifyNumber(int number);

Step 2: Instantiating the delegate 
var numberModifier = new ModifyNumber(FindSquare);

Note that the parameter is the name of the method that we want to reference with the delegate.

Step 3: Using the delegate
int number = numberModifier(5);

class Program {
 delegate int ModifyNumber(int number);

 static int FindSquare(int number)
 {
  return (number * number);
 }

 static void Main(string[] args)
 {
  var numberModifier = new ModifyNumber(FindSquare);
  int temp = numberModifier(5);
  Console.WriteLine(temp);
 }
}

C# Program
delegate simple example to modify a number

Output
 25                                      

Delegate Chaining

The benefit of using delegate is that it allows chaining of method calls in a single delegate reference.

like, delegate "print" can point to two different methods
1. printing the output to console
2. saving the output in a log file

But how? Let's see this in action.


Consider the following two methods:

static void WriteToConsole(string name)
{
    Console.WriteLine("Name is : " + name);
}

static void WriteToFile(string name)
{
    //Code to write name to file
    Console.WriteLine("Written name to file : " + name);
}

Here, we will be creating a delegate such that calling the delegate will invoke these two methods one by one.

Step 1: Declaring the delegate (Same as we did before)

delegate void NameWriter(string str);

Step 2: Creating new delegate objects pointing to these methods.

var writeToConsole = new NameWriter(WriteToConsole);
var writeToFile = new NameWriter(WriteToFile);

Step 3: Create empty delegate variable.
We will use this delegate to call the chained methods.

NameWriter nameWriter;

Step 4: Setting nameWriter reference to the first method.

nameWriter = writeToConsole;
Notice, how we assigned the variable writeToConsole to the nameWriter variable.

Step 5: Chaining/Appending references of other methods to the delegate.

New references are chained to a delegate in the following manner:

nameWriter += writeToFile;
Here we appended the writeToFile reference to the nameWriter.

Step 6: Using the nameWriter delegate.

nameWriter("Kunal");

The following output will be produced when executing the above code:

C# Program
class Program
{
 static void WriteToConsole(string name)
 {
  Console.WriteLine("Name is : " + name);
 }

 static void WriteToFile(string name)
 {
 //Code to write name to file
  Console.WriteLine("Written name to file : " + name);
 }
 
 /************* Step 1 *************/
 delegate void NameWriter(string str);
 /**********************************/
 
 static void Main(string[] args)
 {
  /************* Step 2 *************/
  var writeToConsole = new NameWriter(WriteToConsole);
  var writeToFile = new NameWriter(WriteToFile);
  /**********************************/
 
  /************* Step 3 *************/
  NameWriter nameWriter;
  /**********************************/
 
  /************* Step 4 *************/
  //appending functionalities to write name
  nameWriter = writeToConsole;
  /**********************************/
 
  /************* Step 5 *************/
  nameWriter += writeToFile;
  /**********************************/
 
  /************* Step 6 *************/
  //write names to console and to file in this single statement
  nameWriter("Kunal");
  /**********************************/
  
  //wait for keypress to exit
  Console.ReadKey();
 }
}

Output:


And done. You just appended multiple references to a single delegate and calling this delegate will call all of the chained methods one by one.

You Might Also Like

0 comments