Tags

C# Func

C# C#

In Microsoft Framework class library, there are some built-in delegates. Action, Predicate and Func are some of them. I have explained Action and Predicate in my previous posts. Action and Predicate delegates has restrictions. Action delegate can take only parameters and does not return anything. Predicate delegate can take parameters but returns only boolean value. To return other than boolean value, Func delegate is used.

Func is a generic delegate that encapsulates a method that can accept parameters and return some value.

Below is the declaration of Func delegates in System namespace.


public delegate TResult Func<out TResult>()
public delegate TResult Func<in T, out TResult>(T arg);
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
...
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, in T16, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16);

There are 17 Func delegates defined in the class library. The first delegate cannot accept parameters and returns Type that are specified by the TResult parameter. Other Func delegate can take upto 16 parameters and return Type that are specified by the TResult parameter. The last type is always the return type.

The in and out in delegate represents Covariance and Contravariance. You can read more about these here.

Usage

We can only store methods in Func delegate that has matching parameters and return type specified in Func delegate type. For example, If we take Func<int, int, string> delegate then we can only store those methods that are taking two int parameters and return string type.

Below is the usage of Func delegate.


static void Main(string[] args)
{
    Func<int, int, string> func = Sum;

    string result = func(2, 4);
    Console.WriteLine(result); //Print Sum: 6
}

public static string Sum(int a, int b)
{
    string str = string.Format("Sum: {0}", (a + b));
    return str;
}

In the above example, I have declared Func delegate with two int parameters and return type of string. Remember the last type is always a return type. We have declared a method Sum which takes two int parameters and returns a string. I have stored that Sum method in the func delegate. We call the delegate in the next line that returns the result of type string. In the last line of Main method, we have printed the result into the Console.

Func with Anonymous functions

We can assign anonymous function directly to delegate. An anonymous function is an inline function which doesn't have any function name. It is declared inline that we don't need separate method. We can use anonymous function wherever a delegate is required. You can read more about anonymous function here.

Below is the usage of Func delegate with anonymous function.


static void Main(string[] args)
{
    Func<int, int, string> func = delegate(int a, int b)
    {
        string str = string.Format("Sum: {0}", (a + b));
        return str;
    };

    string result = func(2, 4);
    Console.WriteLine(result); //Print Sum: 6
}

In the above example, we declared anonymous function using delegate(...){ }. We store that function directly into the func delegate instance. By this way, we don't need to declare separate method. We directly declared inline function. At the end, we called delegate using two int parameters 2 and 4. In the last line, we print the result into the Console.

Func with Lambda Expression

Lambda expression is a shorthand way for declaring anonymous functions. Below is the usage.


static void Main(string[] args)
{
    Func<int, int, string> func = (a, b) => string.Format("Sum: {0}", (a + b));

    string result = func(2, 4);
    Console.WriteLine(result); //Print Sum: 6
}