Thursday 8 September 2016

Func, Action and Predicate

C# 3.0 includes built-in generic delegate types Func and Action, so that you don't need to define custom delegates as above.
Func is a generic delegate included in the System namespace. It has zero or more input parameters and one out parameter. The last parameter is considered as an out parameter.
Func in short is parameterized delegate. In C#, a delegate instance points towards a method. When a caller invokes the delegate, it calls its target method. This way, the caller is not invoking the target method rather invoking the delegate which can call the target method. We do it because it creates an abstraction on invoking the target method. We of course always can invoke a method directly but decoupling of the client and target method is sometimes a need or gives us more flexibility to make things clean and simple.
We can use Func delegate to represent a method that can be passed as a parameter without explicitly declaring a custom delegate.
Why I said it's a parameterized delegate:
delegate TResult Func <out TResult> ();
delegate TResult Func <in T, out TResult> (T arg);

delegate TResult Func <in T1, in T2, out TResult> (T1 arg1, T2 arg2);

Action is a delegate (pointer) to a method, that takes zero, one or more input parameters, but does not return anything.
Func is a delegate (pointer) to a method, that takes zero, one or more input parameters, and returns a value (or reference).
Predicate is a special kind of Func often used for comparisons.
Predicate is a delegate that takes generic parameters and returns boo
Though widely used with Linq, Action and Func are concepts logically independent of Linq. C++ already contained the basic concept in form of typed function pointers.
Here is a small example for Action and Func without using Linq:
The Func and Action generic delegates were introduced in the .NET Framework version 3.5.

Whenever we want to use delegates in our examples or applications, typically we use the following procedure:
  • Define a custom delegate that matches the format of the method.
  • Create an instance of a delegate and point it to a method.
  • Invoke the method.
But, using these 2 Generics delegates we can simply eliminate the above procedure.

Since both the delegates are generic, you will need to specify the underlaying types of each parameters as well while pointing it to a function. For for example Action<type,type,type……>

Action<>
  • The Generic Action<> delegate is defined in the System namespace of microlib.dll
  • This Action<> generic delegate, points to a method that takes up to 16 Parameters and returns void.
Func<>
  • The generic Func<> delegate is used when we want to point to a method that returns a value.
  • This delegate can point to a method that takes up to 16 Parameters and returns a value.
  • Always remember that the final parameter of Func<> is always the return value of the method. (For examle Func< int, int, string>, this version of the Func<> delegate will take 2 int parameters and returns a string value.)
class Program
{
    static void Main(string[] args)
    {
        Action<int> myAction = new Action<int>(DoSomething);
        myAction(123);           // Prints out "123"
                                 // can be also called as myAction.Invoke(123);

        Func<int, double> myFunc = new Func<int, double>(CalculateSomething);
        Console.WriteLine(myFunc(5));   // Prints out "2.5"
    }

    static void DoSomething(int i)
    {
        Console.WriteLine(i);
    }

    static double CalculateSomething(int i)
    {
        return (double)i/2;
    }
}

No comments:

Post a Comment