Saturday, August 12, 2017

Func vs. Action vs. Predicate




Func vs. Action vs. Predicate
The Func and Action generic delegates were introduced in the .NET Framework version 3.5.
Predicate, Func and Action are inbuilt delegate instances of .NET.
Action and Func are extremely useful tools for reducing duplication in code and decreasing coupling.
Action is a delegate (pointer) to a method, that takes zero, one or more input parameters, but does not return anything.
Action - When you want a delegate for a function that may or may not take parameters and does not return a value. I use these often for anonymous event handlers:
button1.Click += (sender, e) => { /* Do Some Work */ }
  Action – This delegate is used as a function pointer for the method which can take upto 16 parameters and returns void. Some of the examples are as follows:

delegate void Action();
delegate void Action<in T>(T arg);       
delegate void Action<in T1, in T2>(T1 arg, T2 arg);
… the list goes upto T16.

Func is a delegate (pointer) to a method, that takes zero, one or more input parameters, and returns a value (or reference).
  Func – This delegate is used as a function pointer for the method which can take upto 16 parameters and at least return some type value. Some of the examples are as follows:

delegate TResult Func<out TResult>();
delegate TResult Func<in T,out TResult>(T arg);
delegate TResult Func<in T1, in T2,out TResult>(T1 arg, T2 arg)
.. the list goes upto T16.

Func - When you want a delegate for a function that may or may not take parameters and returns a value. The most common example would be Select from LINQ:
var result = someCollection.Select( x => new { x.Name, x.Address });
The only difference between Action and Func is that Func’s last template parameter is the return type.  Funcs have non-void return values.

  Predicate – Predicates are the comparison delegates which take only one generic argument and return bool. These delegates are generally used for the comparison related operations.

public delegate bool Predicate<in T>(T obj);

Predicate is a special kind of Func often used for comparisons.
  Predicate is a Func that always returns a boolean.
A Predicate is a delegate that accepts one or more generic parameters and returns a Boolean value -- you can assume it something like Func<T,bool>. Predicate delegates are typically used to perform search operations on some data based on a set of criteria.

Predicate - When you want a specialized version of a Func that takes evaluates a value against a set of criteria and returns a boolean result (true for a match, false otherwise).
Predicate: essentially Func<T, bool>; asks the question "does the specified argument satisfy the condition represented by the delegate?" Used in things like List.FindAll.
A Predicate delegate is typically used to search items in a collection or a set of data. Here's how the syntax of Predicate delegate looks like.
Predicate<T>
Note that Predicate<T> is basically equivalent to Func<T,bool>.

The difference between Func and Action is simply whether you want the delegate to return a value (use Func) or not (use Action).
Func is probably most commonly used in LINQ - for example in projections:
 list.Select(x => x.SomeProperty)
or filtering:
 list.Where(x => x.SomeValue == someOtherValue)
or key selection:
 list.Join(otherList, x => x.FirstKey, y => y.SecondKey, ...)


Action is more commonly used for things like List<T>.ForEach: execute the given action for each item in the list.

Predicate is just a special cased Func<T, bool>
Predicate is a delegate that takes generic parameters and returns bool
Predicate is mostly used in List<T> for methods like FindAll and RemoveAll.
None of the Func or Action types allow out or ref parameters, so you'll have to define your own delegates if you need to use those e.g.:
public delegate bool TryParse<T>(string s, out T value);

Here is a small example for Action and Func without using Linq:
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;
    }
}

Out of a Customer list , find the customers whose id is 1.
Predicate<Customer> cust = x => x.Id == 1;
Customer customer = custList.Find(cust);

0 comments:

Post a Comment

Twitter Delicious Facebook Digg Stumbleupon Favorites More