December 19, 2009

The Func delegates

When you use the Func<T, TResult> delegate, you do not have to explicitly define a delegate that encapsulates a method with a single parameter.
// The framework defines a number of parameterized delegate types:

public delegate TReturn Func<TReturn>();
public delegate TReturn Func<T0, TReturn>(T0 a0);
public delegate TReturn Func<T0, T1, TReturn>(T0 a0, T1 a1);
public delegate TReturn Func<T0, T1, T2, TReturn>(T0 a0, T1 a1, T2 a2);
public delegate TReturn Func<T0, T1, T2, T3, TReturn>(T0 a0, T1 a1, T2 a2, T3 a3);

In the above delegate types, notice that if there is only one type parameter, it is the return type of the delegate. If there are two type parameters, the first type parameter is the type of the one and only argument, and the second type is the return type of the delegate, and so on.

Let see some examples -

Func which takes no input argument & returns string.
public delegate TReturn Func<TReturn>();
class FuncTest
{
static void Main(string[] args)
{
Func<string> PrintResultMethod = PrintResult;
Console.WriteLine(PrintResultMethod());
}
private static string PrintResult()
{
return "Hello World";
}
}

Func which takes one input param & returns string
public delegate TReturn Func<T0, TReturn>(T0 a0);
class FuncTest
{
static void Main(string[] args)
{
Func<string,string> PrintResultMethod = PrintResult;
Console.WriteLine(PrintResultMethod("Hello "));
}
private static string PrintResult(string inStr)
{
return inStr + " World";
}
}

Func which takes two input params & returns string
public delegate TReturn Func<T0, T1, TReturn>(T0 a0, T1 a1);
class FuncTest
{
static void Main(string[] args)
{
Func<string,string, string> PrintResultMethod = PrintResult;
Console.WriteLine(PrintResultMethod("Hello ", "World"));
}
private static string PrintResult(string inStr1, string inStr2)
{
return inStr1 + inStr2;
}
}
Delegate instead of Func
In pervious examples we have seen the Func which takes one input param & returns string

public delegate TReturn Func<T0, TReturn>(T0 a0);
The above example can be written using delegate as:

delegate string PrintResultMethod(string inStr);
public class DelegateTest
{
    public static void Main()
    {
        // Instantiate delegate  
        PrintResultMethod printResultMethod = PrintResult;

        // Use delegate instance to call PrintResult method
        Console.WriteLine(printResultMethod("Hello"));
    }

    private static string PrintResult(string inStr)
    {
        return inStr + " World";
    }
}


Func with Anonymous Method
The above example can be written using anonymous method as below:

public class FuncWithAnonymousTest
{
public static void Main()
{
Func<string, string> PrintResultMethod = delegate(string inStr)
{ return inStr + " World"; };

Console.WriteLine(PrintResultMethod("Hello"));
}
}
Func with Lambda Expressions 
Following example shows same can be written using Lambda expressions in just two lines:

public class FuncWithLambdaExpressionTest
{
public static void Main()
{
Func<string, string> PrintResultMethod = inStr => inStr + " World";

Console.WriteLine(PrintResultMethod("Hello"));
}
}