Language: EN

csharp-delegados

What are and how to use delegates in C#

A delegate is a type that represents a reference to a function or method. Delegates allow methods to be passed as parameters, assigned to variables, and executed dynamically at runtime.

To do this, the delegate must match the signature (received parameters) by the function, and with its specific return.

Declaration of a delegate

To declare a delegate in C#, the delegate keyword is used, followed by the method signature that the delegate will represent.

delegate ReturnType MyDelegate(Type parameter1...);

Where,

  • ReturnType, the return type of the function we want to delegate
  • Type parameter…, the parameters of the function we want to delegate

For example, if we want to declare a delegate that represents a method that does not return any value and takes two integer parameters, the declaration would look like this:

Basic example

For example, if we wanted to define a delegate that can point to any function that takes a string as a parameter and does not return any value (void), we could do it like this:

public delegate void MyDelegate(string message);

And if we want to declare a delegate that references a function that takes two int parameters and returns a double, the declaration would look like this:

delegate void MyDelegate(int parameter1, int parameter2);

Use of delegates

Assignment of a method to a delegate

Once the delegate has been declared, we can create an instance of the delegate and assign it a method that matches its signature.

We can create it using its constructor

MyDelegate delegate = new MyDelegate(ReferencedFunction);

Or simply assign it

MyDelegate delegate = ReferencedFunction;

Let’s see an example. Suppose we have the ShowMessage (string ...) function.

// Method we want to reference
public static void ShowMessage(string message)
{
	Console.WriteLine("Delegate:" + message);
}

// Delegate definition
public delegate void MyDelegate(string message);

public static void Main(string[] args)
{
	// Now we create a MyDelegate that points to ShowMessage
	MyDelegate delegate = ShowMessage;
}

Here we have,

  • Defined a MyDelegate delegate, which matches the form of ShowMessage.
  • Created a new instance of MyDelegate, called delegate
  • Assigned the delegate instance to ShowMessage.

Invoking a delegate

Once we have defined the delegate, created a delegate, and referenced a function with it, we can invoke it simply by doing () as we would with the original function.

In the previous example, we could invoke delegate simply like this.

// Invocation of the method through the delegate
delegate("Hello, World!");

So it would appear on the screen

Delegate: Hello, World!

Generic Delegates: Func and Action

To simplify the use of delegates, C# has predefined generic delegates. The most common are Action and Func.

  • Action: Represents a method that does not return a value.
  • Func<TResult>: Represents a method that returns a value of type TResult.

Use of Action

Action<string> show = message => Console.WriteLine(message);

show("Hello with Action!");

Use of Func

Func<int, int, int> sum = (a, b) => a + b;
int result = sum(3, 4);

Console.WriteLine("Sum result: " + result);

In general, this is the form you will normally use, instead of defining the delegate explicitly. Especially if it is a temporary use, it is not worth defining in a traditional way.

Multicast Delegates

A Multicast delegate is a delegate that can have more than one method in its invocation. In fact, all C# delegates are Multicast

We see this in this entry read more ⯈

Use of delegates with events

Delegates are the basis of events in C#. An event is a notification sent by an object to indicate the occurrence of an action. Delegates allow you to subscribe to methods that will be called when the event is fired.

We see this in this entry read more ⯈

Practical examples

Delegate that does not return anything

Here we have an example of a delegate that does not return anything (void).

// Declaration of the delegate that does not return anything
public delegate void ShowMessageDelegate(string message);

// Method that matches the delegate's signature
public static void ShowMessage(string message)
{
    Console.WriteLine(message); // Print the message
}

// Use
ShowMessageDelegate showMessage = ShowMessage; // Assign the method to the delegate
showMessage("Hello, World!"); // Invoke the delegate

Delegate that returns a value

Here is an example of a delegate that returns a value. In the example, the delegate takes two integers as parameters and returns an integer.

// Declaration of the delegate that returns a value
public delegate int SumDelegate(int a, int b);

// Method that matches the delegate's signature
public static int Sum(int a, int b)
{
    return a + b; // Return the sum of the two numbers
}

// Use
SumDelegate sum = Sum; // Assign the method to the delegate
int result = sum(3, 5); // Invoke the delegate and get the result
Console.WriteLine($"Sum result: {result}"); // Print the result

Generic delegate Action

Let’s see an example that uses a generic delegate Action<T> to represent a method that does not return a value and can take parameters.

// Method that matches the signature of Action
public static void PrintMessage(string message)
{
    Console.WriteLine(message); // Print the message
}

// Use
Action<string> print = PrintMessage; // Assign the method to the Action delegate
print("This is a message using Action."); // Invoke the delegate

Generic delegate Func

Now an example of a generic Func<T delegate that can represent a method that returns a value and can take parameters.

// Method that matches the signature of Func
public static double CalculateCircleArea(double radius)
{
    return Math.PI * radius * radius; // Calculate and return the area of the circle
}

// Use
Func<double, double> calculateArea = CalculateCircleArea; // Assign the method to the Func delegate

double area = calculateArea(5.0); // Invoke the delegate and get the result
Console.WriteLine($"Circle area: {area}"); // Print the circle area

Delegate as a parameter in a Method

In this example, we will see how to pass a delegate as a parameter to another method,

// Declaration of the delegate that does not return anything
public delegate void OperationDelegate(int x, int y);

// Method that uses a delegate as a parameter
public static void PerformOperation(int a, int b, OperationDelegate operation)
{
    operation(a, b); // Invoke the delegate
}

// Methods that match the delegate's signature
public static void Add(int a, int b)
{
    Console.WriteLine($"Addition: {a + b}");
}

public static void Multiply(int a, int b)
{
    Console.WriteLine($"Product: {a * b}");
}

// Use
OperationDelegate additionOperation = Add; // Assign the Add method to the delegate
OperationDelegate multiplicationOperation = Multiply; // Assign the Multiply method to the delegate

PerformOperation(3, 4, additionOperation); // Pass the delegate to the method
PerformOperation(3, 4, multiplicationOperation); // Pass the delegate to the method