Delegados: Predicado x Ação x Func


137

Alguém pode fornecer uma boa explicação (com exemplos) dos três delegados mais importantes:

  • Predicado
  • Açao
  • Func

Respostas:


180
  • Predicate: essencialmente Func<T, bool>; faz a pergunta "o argumento especificado satisfaz a condição representada pelo delegado?" Usado em coisas como List.FindAll.

  • Action: Execute uma ação de acordo com os argumentos. Finalidade muito geral. Não é muito usado no LINQ, pois implica efeitos colaterais, basicamente.

  • Func: Usado extensivamente no LINQ, geralmente para transformar o argumento, por exemplo, projetando uma estrutura complexa em uma propriedade.

Outros delegados importantes:

  • EventHandler/ EventHandler<T>: Usado em todo o WinForms

  • Comparison<T>: Como, IComparer<T>mas na forma de delegado.


3
Há também System.Converter<TInput, TOutput>, embora raramente seja usado.
G-Wiz

4
O conversor é um bom representante quando é necessária muita conversão de modelo em classes de negócios, ou seja, stum.de/2009/12/23/…
Michael Stum

EventHandler/EventHandler<T>também aparecerão fora do WinForms.
Andy

@ Andy: Um pouco ... Mas menos no WPF, por exemplo. Concordo que não há nada específico para o WinForms.
Jon Skeet

48

Action, Funce Predicatetodos pertencem à família delegada.

Action : A ação pode aceitar n parâmetros de entrada, mas retorna nulo.

Func: Func pode receber n parâmetros de entrada, mas sempre retornará o resultado do tipo fornecido. Func<T1,T2,T3,TResult>, aqui T1, T2, T3 são parâmetros de entrada e TResult é a saída dele.

Predicate: Predicado também é uma forma de Func, mas sempre retornará bool. Em palavras simples, é invólucro Func<T,bool>.


MELHOR e resposta mais simples eu encontrei sempre com relação a esta questão
Reyan Chougle

@ReyanChougle: Ainda bem que você acha útil.
Rahul Garg

9

Além da resposta de Jon, também há

  • Converter<TInput, TOutput>: É essencialmente Func<TInput, TOutput>, mas com semântica. Usado por List.ConvertAll e Array.ConvertAll, mas pessoalmente não o vi em nenhum outro lugar.

4

O MethodInvoker é aquele que os desenvolvedores do WinForms podem usar; não aceita argumentos e não retorna resultados. Ele antecede a Ação e ainda é frequentemente usado ao invocar o thread da interface do usuário, pois BeginInvoke () et al aceitam um Delegado não digitado; embora a ação faça o mesmo.

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

Eu também estaria ciente de ThreadStart e ParameterizedThreadStart; novamente, a maioria das pessoas substitui uma ação nos dias de hoje.


3

Predicate, Func e Action são instâncias delegadas incorporadas do .NET. Cada uma dessas instâncias delegadas pode se referir ou apontar para métodos de usuário com assinatura específica.

Delegado de ação - As instâncias de delegado de ação podem apontar para métodos que recebem argumentos e retornos nulos.

Delegado do Func - a instância do delegado do Func pode apontar para métodos que recebem um número variável de argumentos e retornam algum tipo.

Predicado - Predicados são semelhantes às funções de delegação de funções e podem apontar para métodos que recebem um número variável de argumentos e retornam um tipo de bool.


2

Ação e Func com 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 é mais compatível com LINQ, pode ser passado como um parâmetro. (sem ponto)

Predicado não pode, tem que ser embrulhado novamente.

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

Um exemplo simples sobre os argumentos e o que retutn cada tipo

Este Func recebe dois argumentos int e retorna um int.Func sempre tem o tipo de retorno

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

Nesse caso, func não possui argumentos, mas retorna uma string

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

Esta ação pega dois argumentos int e retorna nulo

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

Este Predicado aceita um argumento e sempre retorna bool.Geralmente Predicados sempre retornam bool.

Predicate<int> isPositive = (x) => x > 0;
Console.WriteLine(isPositive(5));//Print True
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.