C# - Simplificando seus métodos anônimos com Expressões lambdas


 Neste artigo eu vou mostrar como podemos usar expressões lambdas para simplificar e melhorar seu código C# substituindo os métodos anônimos.

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.

Eu não vou entrar em detalhes sobre o que é um delegate (para detalhes leia o artigo) vou apenas apresentar a sua definição (uma delas):

Um Delegate é um ponteiro para um método. Um Delegate 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 para fazer isso seria manter o tipo de parâmetro e o tipo de retorno.

A muito tempo atrás, na versão 2.0 da plataforma .NET, os métodos anônimos foram introduzidos.

A idéia por trás dos métodos anônimos é escrever métodos inline no código sem declarar um método formal com nome; normalmente eles são usados para pequenos pequenos que não precisam ser reutilizados.

Recursos usados :

Usando métodos anônimos

Vamos definir uma tarefa bem simples e que ocorre com freqüência: verificar se um item esta em uma lista aplicando um critério de seleção.

Assim vamos supor que temos uma lista de nomes e desejamos saber se um nome esta na lista.

Abra o Visual Studio 2013 Express for windows desktop e crie um novo projeto do tipo Console Application com o nome MetodosAnonimos.

A seguir implemente o código abaixo:

1- Código C# tradicional usado pelo programador 'acomodado'

using System.Collections.Generic;
namespace MetodosAnonimos
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> nomes = new List<string>();
            nomes.Add("Macoratti");
            nomes.Add("Miriam");
            nomes.Add("Jessica");
            nomes.Add("Jefferson");
            nomes.Add("Janice");
            nomes.Add("Marcia");
            nomes.Add("Bianca");
            nomes.Add("Carlos");
            nomes.Add("Yuri");
            string resultado = nomes.Find(VerificaNomeNaLista);
            Console.WriteLine(resultado);
            Console.ReadKey();
        }
        public static bool VerificaNomeNaLista(string _nome)
        {
            return _nome.Equals("Macoratti");
        }
    }
}

Este é o código tradicional que um programador C# que não conhece métodos anônimos usaria e ele funciona.

Mas ao invés de declarar um ou mais métodos em sua classe podemos escrever o método diretamente usando métodos anônimos. Veja como ficaria o código feito por um programador que conhece métodos anônimos:

2- Código C# usando métodos anônimos pelo programador 'experto'

using System;
using System.Collections.Generic;
namespace MetodosAnonimos2
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> nomes = new List<string>();
            nomes.Add("Macoratti");
            nomes.Add("Miriam");
            nomes.Add("Jessica");
            nomes.Add("Jefferson");
            nomes.Add("Janice");
            nomes.Add("Marcia");
            nomes.Add("Bianca");
            nomes.Add("Carlos");
            nomes.Add("Yuri");
            string resultado = nomes.Find(delegate(string nome)
                                    {
                                          return nome.Equals("Bianca");
                                    });
            Console.WriteLine(resultado);
            Console.ReadKey();
        }
    }
}

Observe que neste código estamos passando em um tipo especial de método inline, o delegate diretamente ao método nomes.Find();

Mas que vantagem Maria leva ???

1 - Você economizou algumas linhas de código. Menos digitação menos erros.
2 - O código foi definido no local onde ele esta sendo usado. Você não tem que procurar por um método no seu código.
3 - O método não tem nome (por isso se chama método anônimo, ora bolas...) e o tipo de retorno esta sendo inferido. Duas preocupações a menos para você tratar.  

Bem, a palavra delegate usada no método esta te incomodando ????

Pois então saiba que você vai ter que se acostumar com ela pois ela é usada em vez do nome do método.

Ponha isso na sua cabeça : Métodos Anônimos são sempre acessados através de um delegate.

Evoluindo para Expressões Lambdas

Pois bem, quem fica parado é poste, não é mesmo. Então a partir da versão 3.0 (estamos na versão 5.0) surgiram as expressões lambdas.

Uma expressão lambda é uma função anônima que você pode usar para criar delegates ou tipos de árvore de expressão. Usando expressões lambda, você pode gravar funções locais que podem ser passadas como argumentos ou serem retornadas como o valor de chamadas de função. Expressões lambda são particularmente úteis para escrever expressões de consulta LINQ. http://msdn.microsoft.com/pt-br/library/vstudio/bb397687.aspx

As expressões lambdas vieram simplificar ainda mais o seu código pois elas permitem que você passe uma expressão embutida como um delegate usando uma sintaxe bem enxuta. Veja como fica o nosso código :

3- Código C# usando expressões lambdas pelo programador 'antenado'

using System;
using System.Collections.Generic;
namespace ExpressoesLambdas
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> nomes = new List<string>();
            nomes.Add("Macoratti");
            nomes.Add("Miriam");
            nomes.Add("Jessica");
            nomes.Add("Jefferson");
            nomes.Add("Janice");
            nomes.Add("Marcia");
            nomes.Add("Bianca");
            nomes.Add("Carlos");
            nomes.Add("Yuri");
            string resultado = nomes.Find(nome => nome.Equals("Bianca"));

            Console.WriteLine(resultado);
            Console.ReadKey();
        }
    }
}

Mas o que é que significa esse símbolo => no código ?

Esse é o famoso operador lambda. Não conhecia ?   Então. muito prazer...   

Veja que a expressão lambda é equivalente ao método anônimo :

 delegate(string nome)
 {
           return nome.Equals("Bianca");
 });
  nome => nome.Equals("Bianca")
Método Anônimo Expressão Lambda

O formato de uma expressão lambda é :

  parâmetros => expressão
O lado esquerdo do operador lambda especifica os parâmetros de entrada (se houver) e o lado direito trata a expressão ou bloco de instruções.

Na expressão lambda usada temos um argumento chamado nome, que é implicitamente tipado como string, e o operador lambda que aplica uma expressão que verifica se o nome é igual a 'Bianca'.

A expressão lambda esta sendo usada como entrada para o método Find().

Você deve estar pensando com seus botões : "Mas e o tipo de retorno ? "

Ora, ora, o tipo de retorno é sempre inferido a partir da assinatura do delegate e a expressão é sempre tratada como um delegate.

Clareou agora...

Você pode usar expressões lambdas em expressões de filtro, classificação , atuar sobre lista e seus métodos.

Segue abaixo alguns exemplos de expressão lambdas aplicadas a nossa lista de strings :    

 
   foreach (string pessoa in nomes.FindAll(p => (p.StartsWith("M"))))
   {
      Console.WriteLine(pessoa);
   }
   Localiza todos os nomes que iniciam com a letra "M"
  
   if (nomes.Exists(e => e.Equals("Marcia")))
   {
     Console.WriteLine("existe uma pessoa chamada Marcia na lista");
   }
   Verifica se um nome existe na lista

  nomes.RemoveAll(p => p.StartsWith("J"));
   Remove todos os nomes que iniciam com "J"

 nomes.ForEach(n => Console.WriteLine(n));

 

     Imprime todos os nomes da lista no console

Nota:  uma lista de inteiros ofereceria mais possibilidades de utilização.

Conclusão: Você tem que aprender a usar expressões lambdas de qualquer jeito. Senão...

Pegue o exemplo do projeto aqui:  MetodosAnonimos.zip

 Porque não vos fizemos saber a virtude e a vinda de nosso Senhor Jesus Cristo, seguindo fábulas artificialmente compostas; mas nós mesmos vimos a sua majestade. (2 Pedro 1:16)

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?


Referências:


José Carlos Macoratti