C# - Funções Anônimas : Expressões Lambdas e Métodos Anônimos
Neste artigo eu vou apresentar os conceitos básicos da linguagem C# sobre funções anônimas, expressões lambdas e métodos anônimos. |
Uma função anônima é uma declaração "in-line" ou expressão que pode ser usada sempre que um tipo de delegate é esperado. Podemos usá-las para inicializar um delegate nomeado ou passar uma função anônima em vez de um tipo de delegado nomeado como um parâmetro de método.
Para você poder acompanhar e entender este artigo você tem que saber o que é um delegate. Se você tem dúvidas leia o meu artigo : C# - Delegates e Eventos : Conceitos básicos e depois prossiga na leitura.
Um Delegate é um ponteiro para um método que pode ser passado como um parâmetro para um método. Podemos mudar a implementação do método dinamicamente em tempo de execução, a única coisa que precisamos observer para fazer isso seria manter o tipo de parâmetro e o tipo de retorno. |
Existem dois tipos de de Funções Anônimas:
Métodos Anônimos (Anonymous Method)
Expressões Lambdas (Lambdas Expressions).
Nas versões anteriores à versão 2.0 da linguagem C#, a única maneira de declarar um delegate era usando métodos nomeados. A partir da versão 2.0, a linguagem C# introduziu os métodos anônimos e no C# 3.0 e posterior, as expressões lambdas substituem os métodos anônimos como a melhor maneira de escrever código embutido.
Uma expressão lambda é uma função anônima que pode conter expressões e instruções e pode ser usada para criar delegates ou tipos de árvore de expressão.
Todas as expressões lambdas usam o operador lambda => o qual significa 'vai para'. A sintaxe geral de uma expressão lambda pode ser expressa assim:
( parâmetros de entrada ) => {expressão ou bloco de instrução};
No lado esquerdo do operador lambda temos os parâmetros de entrada, que podem ser tipos implícitos ou explícitos, a serem passados para o método;
No lado direito temos temos o método, expressão ou bloco de código que será executado;
Ex: numero => numero % 2 == 1
numero é o parâmetro de entrada;
numero % 2 == 1 é a expressão a ser executada;
Podemos ler essa expressão da seguinte forma:
O parâmetro de entrada chamado numero vai para a função anônima a qual retorna true se o parâmetro de entrada for um número ímpar.
Recursos usados :
Usando Expressões lambdas
As expressões lambdas usam uma sintaxe mais resumida, também chamada de, açucarada (sugar sintax), permitindo escrever um código mais legível e sucinto.
Vejamos um exemplo usando a expressão lambda acima que retornar os números impares de uma lista de números :
A expressão lambda usada no código é :
List<int> impares = numeros.Where(n => n % 2 == 1).ToList();
O código obtém uma lista dos números impares que depois é percorrida por um laço foreach.
Ainda usando a expressão lambda acima poderíamos usar outra sintaxe para retornar true ou false para um número impar:
Neste código a sintaxe ficou assim:
numeros.ToList().ForEach(n => Console.WriteLine(n % 2 == 1));
O código verifica cada número da lista e retorna true se ele for impar e false se não for impar.
Método Anônimo x Expressão Lambda
Vejamos um exemplo onde vamos verificar se um nome esta em uma lista usando um método anônimo e depois usando expressão lambda:
1- Método Anônimo
namespace Metodo_Anonimo
{
class Program
{
static void Main(string[] args)
{
List<string> nomes = new List<string> { "Yuri", "Jefferson", "Jessica", "Janice", "Miriam" };
string resultado = nomes.Find(delegate(string nome)
{
return nome.StartsWith("M");
});
Console.WriteLine(resultado);
Console.ReadKey();
}
}
}
|
2- Expressão Lambda
namespace Metodo_Anonimo { class Program { static void Main(string[] args) { List<string> nomes = new List<string> { "Yuri", "Jefferson", "Jessica", "Janice", "Miriam" }; string resultado = nomes.Find(nome => nome.StartsWith("M")); Console.WriteLine(resultado); |
O resultado obtido é o mesmo mas o código ficou mais sucinto.
LINQ x Expressão Lambada
Agora vamos comparar a utilização de uma expressão LINQ com uma expressão lambda em um exemplo.
Neste exemplo vamos obter os números pares em um array de números inteiros usando LINQ e uma expressão lambda:
using System.Linq;
using System;
namespace LINQ_Lambda
{
class Program
{
static void Main(string[] args)
{
// Declarando o vetor de números inteiros
int[] numeros = { 1, 2, 3, 4, 5, 6 , 7 , 8 , 9, 10, 11, 12 };
// usando LINQ
var numerosPares_Linq = (from num in numeros
where (num % 2 == 0)
select num);
foreach( int n in numerosPares_Linq)
{
Console.WriteLine("Pares (Linq) : " + n);
}
Console.ReadKey();
// usando uma Expressão lambada
var numerosPares_Lambda = numeros.Where(num => num % 2 == 0);
foreach (int n in numerosPares_Lambda)
{
Console.WriteLine("Pares (Lambda) : " + n);
}
Console.ReadKey();
}
}
}
|
Comparando temos:
//Linq var numerosPares_Linq = (from num in numeros where (num % 2 == 0) select num); |
//Expressão Lambda var numerosPares_Lambda = numeros.Where(num => num % 2 == 0); |
Com esses exemplos podemos verificar que as expressões lambdas realmente simplificam a sintaxe visto que não precisamos especificar o nome do método, seu tipo de retorno e modificador de acesso. Além disso elas tornam o código mais legível pois não temos que procurar no código a definição do método.
Pegue o exemplo do projeto aqui: Expressao_lambda.zip
Lucas 5:31 - E Jesus, respondendo, disse-lhes: Não necessitam de médico os que estão sãos, mas, sim, os que estão enfermos;
Lucas 5:32 - Eu não vim chamar os justos, mas, sim, os pecadores, ao arrependimento.
Referências: