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.
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.
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);
(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?
Using Interfaces vs. Func or Action
I guess you can compare an Action
or Func
with an interface containing one method, with the difference that you can supply any Action
or Func
that meets the parameter / return value requirements, where when using interfaces, the supplied object must implement that interface.
Perhaps you could call Action
and Func
"anonymous single method interfaces".
If you look at the design perspective though, your class model would be a drawing of blocks without any lines between them.
Related Topics
Performance Difference for Control Structures 'For' and 'Foreach' in C#
Service Hangs Up at Waitforexit After Calling Batch File
Custom Collection Initializers
Null or Default Comparison of Generic Argument in C#
The Need for Volatile Modifier in Double Checked Locking in .Net
Pass Connection String to Code-First Dbcontext
Checking If a Bit Is Set or Not
How to Deserialize a JSON Property That Can Be Two Different Data Types Using JSON.Net
Prevent Using Dispatcher.Invoke in Wpf Code
How to Do Template Specialization in C#
Setting the User-Agent Header for a Webclient Request
How to Get a Human-Readable File Size in Bytes Abbreviation Using .Net
How to Use the Ternary Operator Inside an Interpolated String
Entity Framework Very Slow to Load for First Time After Every Compilation
Escape Invalid Xml Characters in C#
How to Create a Hashcode in .Net (C#) for a String That Is Safe to Store in a Database