Delegati: Predicato vs. Azione vs. Func


137

Qualcuno può fornire una buona spiegazione (si spera con esempi) di questi 3 delegati più importanti:

  • Predicato
  • Azione
  • Func

Risposte:


180
  • Predicate: essenzialmente Func<T, bool>; pone la domanda "l'argomento specificato soddisfa la condizione rappresentata dal delegato?" Utilizzato in cose come List.FindAll.

  • Action: Esegue un'azione dati gli argomenti. Scopo molto generale. Non utilizzato molto in LINQ in quanto implica effetti collaterali, fondamentalmente.

  • Func: Ampiamente utilizzato in LINQ, di solito per trasformare l'argomento, ad esempio proiettando una struttura complessa su una proprietà.

Altri delegati importanti:

  • EventHandler/ EventHandler<T>: Utilizzato in tutto WinForms

  • Comparison<T>: Come IComparer<T>ma in forma delegata.


3
C'è anche System.Converter<TInput, TOutput>, sebbene sia usato raramente.
G-Wiz,

4
Il convertitore è un buon delegato quando è necessaria molta conversione del modello in classi aziendali, ad esempio stum.de/2009/12/23/…
Michael Stum

EventHandler/EventHandler<T>apparire anche al di fuori di WinForms.
Andy,

@Andy: in qualche modo ... Ma meno in WPF per esempio. Sono d'accordo che non esiste nulla di specifico per WinForms.
Jon Skeet,

48

Action, FuncE Predicatetutti appartengono alla famiglia delegato.

Action : L'azione può accettare n parametri di input ma restituisce null.

Func: Func può accettare n parametri di input ma restituirà sempre il risultato del tipo fornito. Func<T1,T2,T3,TResult>, qui T1, T2, T3 sono parametri di input e TResult ne è l'output.

Predicate: Il predicato è anche una forma di Func ma restituirà sempre valore. In parole semplici è avvolgente Func<T,bool>.


La risposta MIGLIORE e PIÙ SEMPLICE che abbia mai trovato in merito a questa domanda
Reyan Chougle,

@ReyanChougle: Felice, lo trovi utile.
Rahul Garg,

9

Oltre alla risposta di Jon, c'è anche

  • Converter<TInput, TOutput>: È essenzialmente Func<TInput, TOutput>, ma con la semantica. Utilizzato da List.ConvertAll e Array.ConvertAll, ma personalmente non l'ho visto altrove.

4

MethodInvoker è uno che gli sviluppatori di WinForms possono usare; non accetta argomenti e non restituisce risultati. È precedente ad Action ed è ancora spesso usato quando si richiama sul thread dell'interfaccia utente poiché BeginInvoke () et al accettano un delegato non tipizzato; sebbene anche l'azione farà altrettanto.

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

Sarei anche a conoscenza di ThreadStart e ParameterizedThreadStart; ancora una volta la maggior parte delle persone sostituirà un'azione in questi giorni.


3

Predicate, Func e Action sono istanze delegate integrate di .NET. Ognuna di queste istanze delegate può fare riferimento o puntare a metodi utente con firma specifica.

Delegato di azione: le istanze del delegato di azione potrebbero puntare a metodi che accettano argomenti e restituiscono nulla.

Func delegate: l'istanza delegata di Func potrebbe puntare a metodi che accettano un numero variabile di argomenti e restituiscono un tipo.

Predicato: i predicati sono simili alle istanze del delegato di funzione e potrebbero indicare metodi che accettano un numero variabile di argomenti e restituiscono un tipo bool.


2

Azione e Func con 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

Func è più compatibile con LINQ, può essere passato come parametro. (Privo di punto)

Il predicato non può, deve essere avvolto di nuovo.

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

2

Un semplice esempio sugli argomenti e su cosa ripeti ogni tipo

Questo Func accetta due argomenti int e restituisce un int.Func ha sempre un tipo restituito

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

In questo caso, func non ha argomenti ma restituisce una stringa

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

Questa azione accetta due argomenti int e restituisce il vuoto

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

Questo Predicato prende un argomento e restituisce sempre il bool. Generalmente i Predicati restituiscono sempre il bool.

Predicate<int> isPositive = (x) => x > 0;
Console.WriteLine(isPositive(5));//Print True
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.