Func, Action e Predicate
ResumoUm delegate é uma referência a um método — permite passar comportamento como parâmetro.
Func,ActionePredicatesão delegates genéricos prontos que cobrem quase todos os casos.
1. Objetivos de Aprendizagem#
- Entender o que é um delegate.
- Usar
Func<>,Action<>ePredicate<>. - Passar comportamento como argumento.
2. Pré-requisitos#
- Generics (tópico 7.2).
3. Conceito#
Um delegate é um tipo que representa a assinatura de um método — como um "ponteiro de função" tipado. Isso permite tratar comportamento como dado: passar, guardar e invocar métodos.
Delegates genéricos prontos:
Func<..., TResult>: recebe argumentos e retorna valor. Ex.:Func<int, int, int>(doisint→int).Action<...>: recebe argumentos e não retorna nada (void).Predicate<T>: recebe umTe retornabool(um teste).
O porquê: é o que torna o LINQ possível — Where(p => p.Preco > 100) recebe uma função como argumento.
4. Mão na Massa#
4.1. Setup#
dotnet new console -n Catalog.Delegates
cd Catalog.Delegates
4.2. Implementação Passo a Passo#
FunceAction:
Func<decimal, decimal> comImposto = preco => preco * 1.1m;
Action<string> log = msg => Console.WriteLine($"[log] {msg}");
Console.WriteLine(comImposto(100m)); // 110
log("processando");
Predicatee passar comportamento:
Predicate<int> ehPar = n => n % 2 == 0;
Console.WriteLine(ehPar(4)); // True
// Método que recebe comportamento como parâmetro:
void ParaCada<T>(IEnumerable<T> itens, Action<T> acao)
{
foreach (var item in itens) acao(item);
}
ParaCada(new[] { "a", "b" }, x => Console.WriteLine(x.ToUpper()));
4.3. Executando#
dotnet run
5. Exemplo Completo#
ParaCada(itens, acao) demonstra a ideia central: quem chama decide o que fazer com cada item, passando uma Action. É o mesmo mecanismo que o LINQ usa internamente.
6. Boas Práticas e Armadilhas#
| Faça | Evite |
|---|---|
Usar Func/Action/Predicate prontos | Declarar delegates customizados quando os genéricos bastam |
| Manter as funções curtas e sem efeitos colaterais surpreendentes | Lambdas gigantes que escondem lógica complexa |
Nota
FunceActionsuportam vários parâmetros genéricos (Func<T1,T2,...,TResult>). O último parâmetro deFuncé sempre o tipo de retorno.
7. Segurança e Produção#
- Passar comportamento (estratégias) desacopla o "como" do "quando", facilitando testar cada parte isoladamente.
8. Exercícios#
- Fácil: crie um
Func<int,int>que dobra um número. - Médio: escreva um método que recebe um
Predicate<int>e filtra uma lista. - Desafio: implemente uma calculadora que recebe a operação como
Func<decimal,decimal,decimal>.
9. Resumo#
Delegates representam métodos como dados. Func retorna valor, Action não retorna, Predicate testa. Eles habilitam passar comportamento como argumento — a base do LINQ.
10. Próximos Passos#
A seguir, a forma concisa de escrever delegates: expressões lambda.
11. Referências#
- Microsoft Learn — Delegates
- Microsoft Learn — Func<TResult>
- Microsoft Learn — Action