
Apesar de existirem no C# desde a versão 3.0, muitas pessoas têm dúvidas sobre o que são as expressões lambda.
Então, respondendo rápido, expressões lambda são funções anônimas expressas em uma sintaxe mais simples.
Basicamente, uma expressão lambda possui duas partes:
(x, y) => x + y;
____ _____
| |
| corpo da função
parâmetros
A expressão acima é equivalente a:
delegate(int x, int y) { return x + y; };
Elas podem ter ou não parâmetros, e também podem retornar valor ou não.
// Sem nenhum parâmetro e sem retornar valor
() => Console.WriteLine();
// Sem nenhum parâmetro e retornando valor
() => Math.PI;
// Também pode ser expressa assim:
() => { return Math.PI; };
// Com um parâmetro e retornando valor
(numero) => numero * numero;
// Com dois parâmetros e retornando valor booleano.
(a, b) => a > b;
Uma expressão lambda pode ser atribuída a uma variável, pode ser passada como parâmetro para um método/função e pode ser retornada de um método/função:
// Atribuindo a expressão lambda à variável fn.
Func<int, int, int> fn = (x, y) => x * y;
// Para executar a função fn:
int resultado = fn(2, 3);
No caso acima, o tipo da variável fn é Func<int, int, int>, o que significa que possui 2 parâmetros int de entrada (os dois int da esquerda) e retorna o valor int (o int da direita). Se minha expressão lambda tivesse 3 parâmetros long e retornasse string, ela seria do tipoFunc<long, long, long, string>. Entendeu? O parâmetro genérico mais a direita sempre será o tipo de retorno da expressão lambda, e os outros serão os tipos dos parâmetros.
Func<long, long, long, string> funcao = (x, y, z) => string.Format("{0} {1} {2}", x, y, z);
// ---------------- ------ ------- -------------------------------------
// | | | |
// parâmetros retorno 3 parâmetros retorno (string)
As expressões lambda do tipo Func<> são as que retornam valor (como no exemplo acima).
Então, expressões lambda do tipo Func<>:
- Retornam valor;
- Podem receber qualquer quantidade de parâmetros;
- Os parâmetros de tipo de Func<> referem-se aos parâmetros da expressão lambda, exceto o último à direita, que refere-se ao tipo de retorno.
Existem também as expressões lambda que recebem apenas um parâmetro e retornam true ou false, e que podem ser expressas através do tipo Predicate<>:
// Expressões do tipo Predicate só recebem um argumento e retornam true ou false.
Predicate<string> fnNotNull = (n1) => n1 != null;
// Executando...
fnNotNull("Teste"); // true
fnNotNull(null); // false
Então, expressões lambda do tipo Predicate<>:
- Recebem apenas um parâmetro;
- Sempre retornam bool (true ou false).
E finalmente, as expressões lambda que não retornam valor são do tipo Action<>:
// Expressão lambda com dois parâmetros int que não retorna valor.
Action<int, int> func = (a, b) => Console.WriteLine("{0} e {1}", a, b);
// Executando a função func, que deve imprimir "10 e 20" no console:
func(10, 20);
// Sem nenhum parâmetro de entrada e sem retornar valor
Action func2 = () => Console.WriteLine("Hello World!");
// Executando func2 (Saída "Hello World!"):
func2();
Como expressões do tipo Action<> não retornam valor, os tipos genéricos são somente os parâmetros de entrada (se houverem). Se não houverem, use apenas Action.
Então, expressões lambda do tipo Action:
- Não retornam valor (void);
- Podem receber qualquer quantidade de parâmetros.
Então, agora que sabemos tudo de expressões lambda em C#, vamos brincar um pouco!
// Cálculo do delta
Func<int, int, int, int> fnDelta = (a, b, c) => b * b - 4 * a * c;
// Cálculo do x1 e x2 (raízes)
Func<int, int, int, double> fnX1 = (a, b, delta) => (-b + Math.Sqrt(delta)) / 2 * a;
Func<int, int, int, double> fnX2 = (a, b, delta) => (-b - Math.Sqrt(delta)) / 2 * a;
// Executando as funções...
int valorDelta = fnDelta(1, 4, 1); // valorDelta = 12
if (valorDelta > 0)
{
double valorX1 = fnX1(1, 4, 12); // valorX1 = -0.26794919243112281
double valorX2 = fnX2(1, 4, 12); // valorX2 = -3.7320508075688772
}
Um pensamento em “Expressões Lambda em C# – o básico”