In this article, we are going to talk more about delegates in C#.

A delegate is a reference to a method. We can use a delegate object to pass it to the code in which we want to call a referenced method, without knowing at compile time which method will be invoked.

If you want to see complete navigation of this tutorial, you can do that here C# Intermediate Tutorial.

To download the source code, you can visit Delegates in C# Source Code. 

We are going to divide this article into the following sections:

Delegate Syntax

A base syntax to create a delegate object is:

There are three steps in defining and using delegates:

  • Declaration of our delegate
  • Instantiation, creating the delegate’s object
  • Invocation, where we call a referenced method

It is important to understand that return type of a method and the number of parameters must match delegate’s return type and the number of parameters. Otherwise, we will get a compiler error. We can see in our example that our Write method has a void as return type and only one string parameter as well as our delegate.

Delegates are very useful in the encapsulation of our methods.

C# has the two built-in delegates: Func<T> and Action<T>, there are widely used, so let’s talk more about them.

Func<T> Delegate

This delegate encapsulates a method that has up to sixteen parameters and returns a value of the specified type. So, in other words, we use the Func delegate only with a method that has a return type other than void.

We can instantiate the Func delegate with this syntax:

We can see that the last parameter inside square brackets is a return type. Of course, we don’t have to initialize a delegate object like this, we can do it in another way:

Let’s see how to use Func delegate with an example:

 

Action<T> Delegate

This delegate encapsulates a method that has up to sixteen parameters and doesn’t return any result. So we can assign to this delegate only methods with the void return type.

We can instantiate the Action object with this syntax:

Or, we can use another way:

Let’s see how to use Action delegate with an example:

Practical Example

In this example, we are going to create an application which executes one of three methods (Sum, Subtract, Multiply) based on a single provided parameter. Basically, if we send Sum as a parameter, the Sum method will be executed and so on. First, we will write this example without delegates and then we will refactor that code by introducing delegates.

So let’s start with the first part:

If we start this application, we will get the correct response for any operation we send to the Execute method. But this code could be much better and easier to read without switch-case expression. If we are going to have more than ten operations (for example), this switch block would be very ugly to read and maintain as well.

So, let’s change our code to make it readable, maintainable and more object-oriented. Let’s introduce a new class ExecutionManager:

In here, we create a dictionary which will hold all the operations and all the references towards our methods (Func delegates). Now we can inject this class into the OperationManager class and change the Execute method:

Now, we are configuring all in the constructor of the OperationManager class and executing our action in the Execute method if it contains required operation. At the first look, we can see how much better this code is.

Finally, we need to change the Program class:

Conclusion

In this article, we have learned:

  • How to instantiate a delegate
  • The way to use Func and Action delegates
  • How to write a better code by using delegates

If you have been with us along this entire intermediate series, you have a great knowledge about oop concepts in C#.

If you have enjoyed reading this article and if you would like to receive the notifications about the freshly published .NET Core content we encourage you to subscribe to our blog.