Delegates: Predicate vs. Action vs. Func
Solution 1
Predicate
: essentiallyFunc<T, bool>
; asks the question "does the specified argument satisfy the condition represented by the delegate?" Used in things like List.FindAll.Action
: Perform an action given the arguments. Very general purpose. Not used much in LINQ as it implies side-effects, basically.Func
: Used extensively in LINQ, usually to transform the argument, e.g. by projecting a complex structure to one property.
Other important delegates:
EventHandler
/EventHandler<T>
: Used all over WinFormsComparison<T>
: LikeIComparer<T>
but in delegate form.
Solution 2
Action
, Func
and Predicate
all belong to the delegate family.
Action
: Action can take n input parameters but it returns void.
Func
: Func can take n input parameters but it will always return the result of the provided type. Func<T1,T2,T3,TResult>
, here T1,T2,T3 are input parameters and TResult is the output of it.
Predicate
: Predicate is also a form of Func but it will always return bool. In simple words it is wrapper of Func<T,bool>
.
Solution 3
In addition to Jon's answer, there is also
Converter<TInput, TOutput>
: It's essentiallyFunc<TInput, TOutput>
, but with semantics. Used by List.ConvertAll and Array.ConvertAll, but personally haven't seen it anywhere else.
Solution 4
A simple example about the arguments and what retutn each type
This Func take two int arguments and return an int.Func always has return type
Func<int, int, int> sum = (a, b) => a + b;
Console.WriteLine(sum(3, 5));//Print 8
In this case func doesn't have arguments but return a string
Func<string> print = () => "Hello world";
Console.WriteLine(print());//Print Hello world
This Action take two int arguments and return void
Action<int, int> displayInput = (x, y) => Console.WriteLine("First number is :" + x + " , Second number is "+ y);
displayInput(4, 6); //Print First number is :4 , Second number is :6
This Predicate take one argument and always return bool.Generally Predicates always return bool.
Predicate<int> isPositive = (x) => x > 0;
Console.WriteLine(isPositive(5));//Print True
Solution 5
MethodInvoker is one which WinForms developers may use; it accepts no arguments and returns no results. It predates Action, and is still often used when invoking onto the UI thread since BeginInvoke() et al accept an untyped Delegate; although Action will do just as well.
myForm.BeginInvoke((MethodInvoker)delegate
{
MessageBox.Show("Hello, world...");
});
I'd also be aware of ThreadStart and ParameterizedThreadStart; again most people will substitute an Action these days.
Related videos on Youtube
Andrew
By day developing web apps for the man. By night developing web apps for the world! Web apps, tools, games: https://appzaza.com
Updated on April 24, 2022Comments
-
Andrew about 2 years
Can someone provide a good explanation (hopefully with examples) of these 3 most important delegates:
- Predicate
- Action
- Func
-
G-Wiz over 14 yearsThere's also
System.Converter<TInput, TOutput>
, though it's rarely used. -
Michael Stum over 14 yearsThe Converter is a nice delegate when a lot of Converting of Model into Business classes is needed, i.e. stum.de/2009/12/23/…
-
Andy almost 9 years
EventHandler/EventHandler<T>
appear all over outside of WinForms too. -
Jon Skeet almost 9 years@Andy: Somewhat... But less so in WPF for example. I agree that there's nothing WinForms-specific to it.