Avec des exemples réels et leur utilisation, quelqu'un peut-il m'aider à comprendre:
La différence entre Func
et Action
consiste simplement à demander au délégué de renvoyer une valeur (utilisez Func
) ou non (utilisez Action
).
Func
est probablement le plus couramment utilisé dans LINQ - par exemple dans les projections:
list.Select(x => x.SomeProperty)
ou filtrer:
list.Where(x => x.SomeValue == someOtherValue)
ou sélection de clé:
list.Join(otherList, x => x.FirstKey, y => y.SecondKey, ...)
Action
est plus couramment utilisé pour des opérations telles que List<T>.ForEach
: exécute l'action indiquée pour chaque élément de la liste. J'utilise ceci moins souvent que Func
, bien que je do utilise parfois la version sans paramètre pour des choses comme Control.BeginInvoke
et Dispatcher.BeginInvoke
.
Predicate
n'est qu'un cas particulier Func<T, bool>
réellement introduit avant tous les Func
et la plupart des délégués Action
. Je suppose que si nous avions déjà eu Func
et Action
sous leurs différentes formes, Predicate
n'aurait pas été introduit ... bien que cela soit fait donne un certain sens à l'utilisation du délégué, alors que Func
et Action
sont utilisés à des fins très différentes.
Predicate
est principalement utilisé dans List<T>
pour des méthodes telles que FindAll
et RemoveAll
.
Action est un délégué (pointeur) à une méthode, qui prend zéro, un ou plusieurs paramètres d'entrée, mais ne renvoie rien.
Func est un délégué (pointeur) à une méthode, qui prend zéro, un ou plusieurs paramètres d'entrée et renvoie une valeur (ou une référence).
Predicate est un type spécial de Func souvent utilisé pour les comparaisons.
Bien que largement utilisés avec Linq, Action et Func sont des concepts logiquement indépendants de Linq. C++ contenait déjà le concept de base sous la forme de pointeurs de fonctions typés.
Voici un petit exemple pour Action et Func sans utiliser 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;
}
}
Func - Lorsque vous souhaitez un délégué pour une fonction pouvant ou non prendre des paramètres et renvoyer une valeur. L’exemple le plus courant serait Select from LINQ:
var result = someCollection.Select( x => new { x.Name, x.Address });
Action - Lorsque vous souhaitez un délégué pour une fonction pouvant ou non prendre des paramètres et ne pas renvoyer de valeur. J'utilise souvent ces gestionnaires d'événements anonymes:
button1.Click += (sender, e) => { /* Do Some Work */ }
Prédicat - Lorsque vous voulez une version spécialisée d'un Func qui évalue une valeur par rapport à un ensemble de critères et renvoie un résultat booléen (true pour une correspondance, false sinon). Encore une fois, LINQ les utilise fréquemment pour des tâches telles que Où:
var filteredResults = someCollection.Where(x => x.someCriteriaHolder == someCriteria);
Je viens de vérifier et il s'avère que LINQ n'utilise pas de prédicats. Vous ne savez pas pourquoi ils ont pris cette décision… mais théoriquement, c'est toujours un cas où un prédicat conviendrait.