635

This question already has an answer here:

With real examples and their use, can someone please help me understand:

  1. When do we need Func delegate?
  2. When do we need Action delegate?
  3. When do we need Predicates delegate?


  • Even though this is a duplicate it has a more thorough accepted answer - reggaeguitar
  • @reggaeguitar What's interesting is that both of the accepted answer is from Jon Skeet - rafid059

3 답변


810

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. I use this less often than Func, although I do sometimes use the parameterless version for things like Control.BeginInvoke and Dispatcher.BeginInvoke.

Predicate is just a special cased Func<T, bool> really, introduced before all of the Func and most of the Action delegates came along. I suspect that if we'd already had Func and Action in their various guises, Predicate wouldn't have been introduced... although it does impart a certain meaning to the use of the delegate, whereas Func and Action are used for widely disparate purposes.

Predicate is mostly used in List<T> for methods like FindAll and RemoveAll.


  • I rather like seeing Predicate in a function signature. It illustrates that the passed method makes a decision rather than just returns a success code or a different sort of bool. - Ron Warholic
  • Is there any design guideline on whether to prefer Predicate<T> or Func<T,bool>? I like the expressiveness of Predicate, but I've seen recommendations for Func too. - CodesInChaos
  • @Ron: Yes, that's pretty much what my penultimate paragraph was about. - Jon Skeet
  • @CodeInChaos: Not that I've seen. LINQ uses Func throughout, but that's probably for consistency given that many method accepting a Func<T,bool> as a predicate also have an overload taking a Func<T,int,bool> for an indexed predicate. - Jon Skeet
  • i kind'a like how simple you have explained it. func - returns action - performs (method) - Juvil

322

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.

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:

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;
    }
}


  • Predicate is a delegate that takes generic parameters and returns bool - Martin
  • Nice example! Note that you can also invoke myAction by simply calling it: myAction(123);. You don't need to use .Invoke() - romar
  • and just for completeness if you want to use Func which takes no parameters but returns value (or reference) you should write something like this Func<double> myFoo = new Func<double>(foo); and foo definition could be static double foo(){return 1.0;} - A.B.

58

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 });

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 */ }

Predicate - When you want a specialized version of a Func that evaluates a value against a set of criteria and returns a boolean result (true for a match, false otherwise). Again, these are used in LINQ quite frequently for things like Where:

var filteredResults = 
    someCollection.Where(x => x.someCriteriaHolder == someCriteria);

I just double checked and it turns out that LINQ doesn't use Predicates. Not sure why they made that decision...but theoretically it is still a situation where a Predicate would fit.


  • I know this is old, but Predicate was not used by LINQ because it predates the Func and Action that we know today, and the latter two can be used to achieve the exact same result in a much better way. - gparent
  • @gparent, why is it better? I think the readability is better when meaningfully-named delegates are used instead of Func or Action. - Sam
  • It depends how you use delegates, but sometimes the name isn't so important and having to create functions and variables just for one use to me decreases readability. - gparent

Linked


Related

Latest