web-dev-qa-db-fra.com

Délégués: action sur les prédicats

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

  • Prédicat
  • Action
  • Func

Quels autres délégués un développeur C # devrait-il connaître?

À quelle fréquence les utilisez-vous dans le code de production?

117
Sasha
  • 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: Effectue une action en fonction des arguments. But très général. Peu utilisé dans LINQ car cela implique essentiellement des effets secondaires.

  • Func: utilisé de manière extensive 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é.

169
Jon Skeet

Action, Func et Predicate appartiennent tous à 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 renvoie 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: Le prédicat est aussi une forme de Func mais il retournera toujours bool. En termes simples, il s'agit du wrapper de Func<T,bool>.

29
Rahul Garg

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

  • Converter<TInput, TOutput>: Il s'agit essentiellement de Func<TInput, TOutput>, mais avec une sémantique. Utilisé par List.ConvertAll et Array.ConvertAll, mais personnellement, je ne l'ai vu nulle part ailleurs.
9
G-Wiz

MethodInvoker est un logiciel que les développeurs WinForm peuvent utiliser. il n'accepte aucun argument et ne renvoie aucun résultat. Elle est antérieure à Action et est encore souvent utilisée lors de l'appel sur le thread d'interface utilisateur puisque BeginInvoke () et al acceptent un délégué non typé; bien que l'action fasse aussi bien l'affaire.

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

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

4
El Zorko

Les autres ont déjà mentionné les utilisations correctes des délégués spécifiques, mais je voudrais ajouter quelque chose qui complétera leurs réponses. Les noms Func, Action, Predicate ont un arrière-plan mathématique. Pour que les choses restent simples, je vais donner une définition informelle d’une fonction mathématique comme celle-ci:

Une fonction est une relation entre des ensembles. Nous prenons un membre d'un ensemble et l'utilisons comme entrée et la fonction mappe cette entrée à un seul membre de l'autre. En d'autres termes, quelque chose entre en entrée et produit en sortie.

Encore une fois, de manière informelle, un prédicat mathématique est une déclaration qui peut être vraie ou fausse selon ses variables. Comme d'autres ont mentionné une fonction qui retourne un booléen.

Enfin, l’action est une fonction vide (ou la méthode ou la procédure nom -éviter mathématiquement correcte)

3
Christian Rizov

Les prédicats, fonctions et actions 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 prennent des arguments et renvoient void.

Délégué Func - L'instance de délégué Func pourrait pointer vers une ou plusieurs méthodes qui prennent un nombre variable d'arguments et renvoient un type.

Prédicat - Les prédicats ressemblent aux instances de délégué func et peuvent indiquer des méthodes qui prennent un nombre variable d'arguments et renvoient un type bool.

3
IntelligentBinary

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();
2
user7917367

Un exemple simple à propos des arguments et de ce que chaque type retient

Ce Func prend deux arguments int et retourne un int.Func a toujours le 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'argument mais renvoie une chaîne

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

Cette action prend deux arguments int et renvoie null

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 retourne toujours bool. Généralement, les prédicats retournent toujours bool.

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

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

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

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
0
Rm558