Skip to content
Home » Introduction to Delegates in C#

Introduction to Delegates in C#

Spread the love

Today we’ll be talking about delegates in C#.

What is a delegate? Well, it’s a type that references a method with a particular parameter list and return type. When you instantiate a delegate, you can use it to reference any method whose parameter types and return type are compatible.

Delegates can reference both static methods and instance methods. Let’s have a look at some examples with static methods first.

Delegates Referencing Static Methods

I’m going to create a Console App project for my examples. Let’s create a static class and a bunch of static methods in it. Each method should take two string parameters and return nothing (void return type). The methods can be used to explore the characters that make up the two words passed in as arguments. In particular, one function is supposed to print out the difference between the lengths of the two strings. Another method is supposed to print the total length of the words passed in as arguments. Finally, the third method is supposed to print the length of the longer word.

Here’s the code in the CharacterExplorer class:

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

namespace Delegates
{
    static class CharacterExplorer
    {
        public static void LengthDifference(string word1, string word2)
        {
            int diff = Math.Abs(word1.Length - word2.Length);
            Console.WriteLine($"The length difference is {diff} characters.");
        }

        public static void TotalLength(string word1, string word2)
        {
            int total = word1.Length + word2.Length;
            Console.WriteLine($"The total length is {total} characters.");
        }

        public static void LongerWordLength(string word1, string word2)
        {
            int longer = word1.Length >= word2.Length ? word1.Length : word2.Length;
            Console.WriteLine($"The longer word consists of {longer} characters.");
        }
    }
}

The code is pretty straightforward. We have three methods. In some situations we want to call the first method. In other situations we may prefer to call the second or the third method. This can be achieved with delegates.

All the methods have the same signature and return type. This means we can use a delegate to reference any of them. Let’s define such a delegate in the Program.cs file. This delegate will reference any method that takes two string parameters and has a void return type.

We use the delegate keyword to define a delegate. We also need a name for the delegate type. As we’re going to use our delegate to work with the methods defined above, CharacterInfoDel seems a reasonable name. The delegate must be defined with the same signature and return type as the methods. Here’s the code:

namespace Delegates
{
    class Program
    {
        delegate void CharacterInfoDel(string first, string second);
    }
}

Now let’s define a variable of the CharacterInfoDel type in the Program class. We must pass the name of the method that we want the delegate to reference to the constructor. Let’s say it should reference the first method we defined:

class Program
{
    delegate void CharacterInfoDel(string first, string second);

    static void Main(string[] args)
    {
        CharacterInfoDel characterInfoDel = new(CharacterExplorer.LengthDifference);
    }              
}

Now we can use the variable like the method and pass parameters to it as we would to the method. For example:

Now we can static void Main(string[] args)
{
    CharacterInfoDel characterInfoDel = new(CharacterExplorer.LengthDifference);
    characterInfoDel("red", "orange");
    Console.ReadKey();
}
use the variable like the method and pass parameters to it as we would to the method. For example:

If you run the code, you’ll see the following output in the terminal:

The length difference is 3 characters.

You could pass any of the other two methods to the constructor and then use the delegate to invoke that method. So, delegates work with static methods. What about instance methods?

Delegates Referencing Instance Methods

Let’s create a class and move the methods there. This time these are  to be instance methods, so let’s also remove the static keyword. Here’s the new class:

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

namespace Delegates
{
    public class CharacterInfo
    {
        public void LengthDifference(string word1, string word2)
        {
            int diff = Math.Abs(word1.Length - word2.Length);
            Console.WriteLine($"The length difference is {diff} characters.");
        }

        public void TotalLength(string word1, string word2)
        {
            int total = word1.Length + word2.Length;
            Console.WriteLine($"The total length is {total} characters.");
        }

        public void LongerWordLength(string word1, string word2)
        {
            int longer = word1.Length >= word2.Length ? word1.Length : word2.Length;
            Console.WriteLine($"The longer word consists of {longer} characters.");
        }
    }
}

Let’s instantiate the class in the Program class and pass an instance method to the delegate constructor. This time we’ll use the third method:

namespace Delegates
{
    class Program
    {
        delegate void CharacterInfoDel(string first, string second);

        static void Main(string[] args)
        {
            CharacterInfo characterInfo = new();
            CharacterInfoDel characterInfoDel = new(characterInfo.LongerWordLength);
            characterInfoDel(“red”, “orange”);
            Console.ReadKey();
        }              
    }
}

If you run the code, you will see the following output:

The longer word consists of 6 characters.

So, as you can see, delegates work with instance methods as well.

Multicast Delegates

We can also use a delegate to call more than one method. Multicast delegates reference multiple methods. Let’s say we want to call all three methods simultaneously. We use the + operator to achieve that:

namespace Delegates
{
    class Program
    {
        delegate void CharacterInfoDel(string first, string second);

        static void Main(string[] args)
        {
            CharacterInfo characterInfo = new();

            CharacterInfoDel multicastCharacterInfoDel = 
                new CharacterInfoDel(characterInfo.LengthDifference) +
                new CharacterInfoDel(characterInfo.TotalLength) +
                new CharacterInfoDel(characterInfo.LongerWordLength);

            multicastCharacterInfoDel("red", "orange");
            Console.ReadKey();
        }              
    }
}

As you can see in the code, we’re calling multicastCharacterInfoDel and expecting the three methods to be called. Let’s check it out. Here’s the output:

The length difference is 3 characters.
The total length is 9 characters.
The longer word consists of 6 characters.

Looks like it works.

Delegates Passed to a Method

A delegate can be passed as an argument to a method and then called in the body of the method. Let’s define a static method in the Program class, ShowCharacterInfo, that takes our delegate as the first argument. It also takes two strings as arguments. Then we can call the method in the Main method and pass the multicast delegate we created before as the first argument, followed by two strings.

namespace Delegates
{
    class Program
    {
        delegate void CharacterInfoDel(string first, string second);

        static void Main(string[] args)
        {
            CharacterInfo characterInfo = new();

            CharacterInfoDel multicastCharacterInfoDel = 
                new CharacterInfoDel(characterInfo.LengthDifference) +
                new CharacterInfoDel(characterInfo.TotalLength) +
                new CharacterInfoDel(characterInfo.LongerWordLength);

            ShowCharacterInfo(multicastCharacterInfoDel, "pineapple", "apple");
            
            Console.ReadKey();
        }            
        
        static void ShowCharacterInfo(CharacterInfoDel characterInfoDel, string word1, string word2)
        {
            characterInfoDel(word1, word2);
        }
    }
}

If we now run the code, we’ll see the following output:

The length difference is 4 characters.
The total length is 14 characters.
The longer word consists of 9 characters.

So, as you can see, you can pass a delegate as an argument to a method and then call it there. These are just the basics of delegates and there is much more you can do with them, but let’s leave it for another occasion.


Spread the love
Tags:

Leave a Reply