Func vs. Action vs. Predicate
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
.
Delegates: Predicate vs. Action vs. Func
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.
differences between Predicate and Func delegate in C#
Predicate<T>
was introduced in .NET 2.0 with the introduction of generics. It's a delegate taking one parameter and returning a bool
.
However, with the introduction of LINQ in .NET 3.5, a need was identified for two families of generic types - Func
and Action
(the difference being on whether they return anything) taking up to 16 41 generic input parameters and being generic in their return types. If Func
had existed first, Predicate<T>
would never have been created in the first place. It's an unnecessarily specialized delegate type.
For backwards compatibility reasons though, they cannot now remove Predicate<T>
from the framework. Some may argue that its name does convey specific semantic meaning but I'd struggle to identify many situations where any Func<T,bool>
(or Func<T1,T2,bool>
, etc.) wouldn't be considered a predicate.
14 in .NET 3.5, 16 in .NET 4 and later.
Delegates vs Action, Func in C#
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);
Action, Func and Predicate delegates - C#
Predicate<T>
is a delegate that takes a T
and returns a bool
.
It's completely equivalent to Func<T, bool>
.
The difference is that Predicate<T>
was added in .Net 2.0, whereas all of the Func<*>
delegates were added in .Net 3.5. (except the ones with >8 parameters, which were added in .Net 4.0)
The LINQ-like methods in List<T>
(FindAll()
, TrueForAll()
, etc) take Predicate<T>
s.
To answer your second question, void
cannot be used as a generic parameter.
(Func, Action, Predicate) VS Converter and Comparison delegate c#
Now I'm confused in Converter and Comparison delegate,why .Net Framework introduced these 2 delegate flavours for just converting and comparing, when and how to use these 2 over existing 3.
Historically, the delegates were introduced in the opposite order to the order your question suggests.
Predicate<T>
, Converter<TInput, TOutput>
and Comparison<T>
were introduced in .NET 2.0. They were used by List<T>
and a few other types. At this point in time C# didn't support lambda expressions but did support anonymous methods. Delegates were mostly used for event handling and starting threads... supporting them for predicates, conversion and comparison was a baby step, effectively.
Note that Predicate<T>
isn't used for comparisons - it's used for testing a single value. For example, you could have a Predicate<string>
for "Is the string length more than 5 characters?" Comparison<T>
, however, is for comparing values - it's used for sorting.
The Func
and Action
delegates were (mostly - Action<T>
was in .NET 2.0; used by List<T>.ForEach
) introduced in .NET 3.5, with LINQ. That was the time frame in which C# 3 introduced lambda expressions and its LINQ support as well, and suddenly delegates were everywhere. I believe the level of awareness of delegates (and how they could be used) went up massively with C# 3.
Early pre-releases of LINQ used Predicate<T>
instead of Func<T, bool>
, but then additional overloads of Where
were introduced accepting Func<T, int, bool>
to allow the index to be part of the predicate.
I suspect that if the framework were redesigned from scratch, the "special purpose" delegates (Predicate<T>
, Converter<TInput, TOutput>
and Comparison<T>
) might not exist. It's possible that Predicate<T>
and Comparison<T>
would still exist, as they provide additional semantic hints as to the purpose of the delegate which can help readability - but Converter<TInput, TOutput>
really doesn't have any benefits over Func<T, TResult>
.
When to use Action Delegate instead of Predicate Delegate
Predicate delegate as the name says constitutes a Predicate which would match a condition/predicate and return bool
. Where as Action delegate as the signature says doesn't return anything (one way work).
List<string>.RemoveAll()
requires a predicate cause, what if you want to remove all element T
from list which matches a specific condition?
When to use Action Delegate instead of Predicate Delegate
Predicate delegate as the name says constitutes a Predicate which would match a condition/predicate and return bool
. Where as Action delegate as the signature says doesn't return anything (one way work).
List<string>.RemoveAll()
requires a predicate cause, what if you want to remove all element T
from list which matches a specific condition?
When are delegates and Func/Action not interchangeable?
As Jon Skeet answered in the comments, I was missing the fact that Action/Func are literally delegates (I thought it was classes encapsulating delegates) :
namespace System
{
public delegate TResult Func<in T, out TResult>(T arg);
}
So there's no difference between delegates and corresponding Func/Action because Func/Action are delegates.
Related Topics
Is There a Good Way to Convert Between Bitmapsource and Bitmap
Showing a Windows Form on a Secondary Monitor
How to Implement Real Time Data for a Web Page
A Generic Error Occurred in Gdi+ in Bitmap.Save Method
Reliably Stop System.Threading.Timer
Dynamically Access Table in Ef Core 2.0
File I/O with Streams - Best Memory Buffer Size
How to Convert String to Double with Proper Cultureinfo
What Does "Datetime" Mean in C#
Calling Async Methods from a Wcf Service
How to Drag and Move Shapes in C#
Smoothly Connecting Circle Centers
Prevent Using Dispatcher.Invoke in Wpf Code
Mail Sending with Network Credential as True in Windows Form Not Working