Action and Func Delegates in C#

By FoxLearn 2/27/2025 4:45:19 AM   29
Delegates in C# are a powerful feature found in the System.Delegate namespace. They serve various purposes, but the most common ones are:
  • Callback
  • Event Handling

In this post, we will dive deeper into the Action and Func delegates in C#.

Action Delegates:

An Action delegate is a predefined delegate type that points to any method that accepts parameters but does not return a value (i.e., it returns void).

class SampleClass
{
    // Delegate definition
    delegate void PrintMessageDelegate(string message);

    // A method that prints a message
    public static void PrintMessage(string message)
    {
        Console.WriteLine(message);
    }

    static void Main(string[] args)
    {
        // Creating a delegate instance and assigning the method
        PrintMessageDelegate printMessage = PrintMessage;

        // Calling the delegate with a message
        printMessage("Hello, Action Delegate!");

        // Wait for user input before closing
        Console.Read();
    }
}

Output:

Hello, Action Delegate!

In this example:

  • The PrintMessageDelegate delegate is defined to take a single parameter of type string and return void.
  • The method PrintMessage is invoked via the delegate printMessage.
  • The delegate is used to pass the method PrintMessage as a callback, which prints the message.

Func Delegates:

A Func delegate is another predefined delegate type that can point to methods that accept parameters and return a value. Unlike Action delegates, Func delegates are used when you need to return a value of any type from the method.

class SampleClass
{
    // Declare delegate type
    delegate int SquareDelegate(int x);

    // A method that calculates the square of a number
    public static int CalculateSquare(int x)
    {
        return x * x;
    }

    static void Main(string[] args)
    {
        // Create a delegate instance
        SquareDelegate square = CalculateSquare;

        // Invoke the delegate and store the result
        int result = square(5);
        Console.WriteLine("The square is: {0}", result);

        // Alternatively, use a Func delegate
        Func<int, int> squareFunc = CalculateSquare;

        // Invoke the Func delegate and store the result
        int resultFunc = squareFunc(5);
        Console.WriteLine("The square using Func is: {0}", resultFunc);

        Console.Read();
    }
}

Output:

The square is: 25
The square using Func is: 25

In this example:

  • The method CalculateSquare takes an integer x as input and returns the square of the number.
  • We first use a custom delegate (SquareDelegate) to call the method and return the result.
  • Then, we use the Func<int, int> delegate, which automatically matches the signature of the CalculateSquare method, making it easier and more concise.

Both of these delegates are highly useful for callback functions, event handling, or methods that need to be passed around and executed dynamically.