Délégués: Prédicat vs Action vs Func

137

Quelqu'un peut-il fournir une bonne explication (avec un peu de chance avec des exemples) de ces 3 délégués les plus importants:

  • Prédicat
  • action
  • Func
Andrew
la source

Réponses:

180
  • Predicate: essentiellement Func<T, bool>; pose la question "l'argument spécifié satisfait-il la condition représentée par le délégué?" Utilisé dans des choses comme List.FindAll.

  • Action: Effectuez une action en fonction des arguments. Usage très général. Peu utilisé dans LINQ car cela implique des effets secondaires, en gros.

  • Func: Utilisé de manière intensive dans LINQ, généralement pour transformer l'argument, par exemple en projetant une structure complexe sur une propriété.

Autres délégués importants:

  • EventHandler/ EventHandler<T>: Utilisé partout dans WinForms

  • Comparison<T>: Comme IComparer<T>mais sous forme de délégué.

Jon Skeet
la source
3
Il y a aussi System.Converter<TInput, TOutput>, bien qu'il soit rarement utilisé.
G-Wiz le
4
Le convertisseur est un bon délégué lorsque beaucoup de conversion de modèle en classes commerciales est nécessaire, c'est-à-dire stum.de/2009/12/23
Michael Stum
EventHandler/EventHandler<T>apparaissent également partout en dehors de WinForms.
Andy
@Andy: Un peu ... Mais moins dans WPF par exemple. Je reconnais qu'il n'y a rien de spécifique à WinForms.
Jon Skeet
48

Action, Funcet Predicatetous appartiennent à la famille des délégués.

Action : L'action peut prendre n paramètres d'entrée mais elle retourne void.

Func: Func peut prendre n paramètres d'entrée mais il retournera toujours le résultat du type fourni. Func<T1,T2,T3,TResult>, ici T1, T2, T3 sont des paramètres d'entrée et TResult en est la sortie.

Predicate: Predicate est aussi une forme de Func mais il retournera toujours bool. En termes simples, il est enveloppant Func<T,bool>.

Rahul Garg
la source
MEILLEURE et LA PLUS SIMPLE réponse que j'ai trouvée à cette question
Reyan Chougle
@ReyanChougle: Heureux, vous trouvez cela utile.
Rahul Garg du
9

En plus de la réponse de Jon, il y a aussi

  • Converter<TInput, TOutput>: C'est essentiellement Func<TInput, TOutput>, mais avec la sémantique. Utilisé par List.ConvertAll et Array.ConvertAll, mais personnellement je ne l'ai vu nulle part ailleurs.
G-Wiz
la source
4

MethodInvoker est celui que les développeurs WinForms peuvent utiliser; il n'accepte aucun argument et ne renvoie aucun résultat. Il est antérieur à Action, et est encore souvent utilisé lors de l'appel sur le thread d'interface utilisateur puisque BeginInvoke () et al acceptent un Delegate non typé; même si Action fera tout aussi bien.

myForm.BeginInvoke((MethodInvoker)delegate
{
  MessageBox.Show("Hello, world...");
});

Je serais également au courant de ThreadStart et ParameterizedThreadStart; encore une fois, la plupart des gens remplaceront une action ces jours-ci.

El Zorko
la source
3

Predicate, Func et Action sont des instances de délégué intégrées de .NET. Chacune de ces instances de délégué peut faire référence ou pointer vers des méthodes utilisateur avec une signature spécifique.

Délégué d'action - Les instances de délégué d'action peuvent pointer vers des méthodes qui acceptent des arguments et retournent void.

Délégué Func - L'instance de délégué Func peut pointer vers des méthodes prenant un nombre variable d'arguments et renvoyant un type.

Prédicat - Les prédicats sont similaires aux instances de délégué func et peuvent pointer vers des méthodes qui acceptent un nombre variable d'arguments et renvoient un type booléen.

IntelligentBinary
la source
2

Action et Func avec lambda:

person p = new person();
Action<int, int> mydel = p.add;       /*(int a, int b) => { Console.WriteLine(a + b); };*/
Func<string, string> mydel1 = p.conc; /*(string s) => { return "hello" + s; };*/
mydel(2, 3);
string s1=  mydel1(" Akhil");
Console.WriteLine(s1);
Console.ReadLine();
Serrement
la source
2

Func est plus convivial pour LINQ, peut être passé en paramètre. (sans point)

Le prédicat ne peut pas, doit être encapsulé à nouveau.

Predicate<int> IsPositivePred = i => i > 0;
Func<int,bool> IsPositiveFunc = i => i > 0;

new []{2,-4}.Where(i=>IsPositivePred(i)); //Wrap again

new []{2,-4}.Where(IsPositivePred);  //Compile Error
new []{2,-4}.Where(IsPositiveFunc);  //Func as Parameter
Rm558
la source
2

Un exemple simple sur les arguments et ce que retutn chaque type

Cette Func prend deux arguments int et retourne un int.Func a toujours un type de retour

 Func<int, int, int> sum = (a, b) => a + b;
 Console.WriteLine(sum(3, 5));//Print 8

Dans ce cas, func n'a pas d'arguments mais renvoie une chaîne

Func<string> print = () => "Hello world";
Console.WriteLine(print());//Print Hello world

Cette action prend deux arguments int et renvoie 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

Ce prédicat prend un argument et renvoie toujours bool. En général, les prédicats renvoient toujours bool.

Predicate<int> isPositive = (x) => x > 0;
Console.WriteLine(isPositive(5));//Print True
dimath
la source