LINQ - Melhorando seu código C#


Neste artigo vamos recordar alguns conceitos do LINQ e mostrar como ele pode melhorar o seu código C#.

A LINQ - Language Integrated Query - possui uma sintaxe que torna a intenção do código mais óbvia facilitando a sua leitura e o entendimento. Vejamos a seguir alguns cenário nos quais o LINQ pode melhorar o seu código C#.

1- Evitando o uso de foreach e if em coleções para filtrar dados

Você pode evitar a utilização do foreach e cláusulas if dentro do foreach para filtrar dados.

Abaixo temos um exemplo bem simples e ingênuo onde estamos filtrando os usuários não logados usando um laço foreach e cláusulas if:

       static void Main(string[] args)
        {
            var usuarioNaoLogados = new List<User>();
            var usuarios = User.GetUsers();
            foreach (User usuarioAtual in usuarios)
            {
                if (usuarioAtual.Ativo && usuarioAtual.Habilitado)
                {
                    if (!usuarioAtual.Logado)
                    {
                        usuarioNaoLogados.Add(usuarioAtual);
                    }
                }
            }
            Console.ReadLine();
        }

O mesmo código usando LINQ ficaria assim:

       static void Main(string[] args)
        {
            var usuarios = User.GetUsers();
            var usuariosNaoLogados = from usuarioAtual in usuarios
                                                       where usuarioAtual.Ativo && usuarioAtual.Habilitado && !usuarioAtual.Logado
                                                       select usuarioAtual;           
            Console.ReadLine();
        }

2- Selecionando um determinado número de itens em uma coleção

Quando precisamos selecionar um determinado número de itens em uma coleção na abordagem clássica usamos um contador e controlamos a contagem para decidir quando sair do laço :

Nota: O código usado é típico de um iniciante na linguagem C#

       static void Main(string[] args)
        {
            var usuarioNaoLogados = new List<User>();
            var usuarios = User.GetUsers();
            for (int i = 0; i < usuarios.Count; i++)
            {
                if(usuarios[i].Ativo && usuarios[i].Habilitado)
                 {
                    if(!usuarios[i].Logado)
                        usuarioNaoLogados.Add(usuarios[i]);
                }
                if(usuarioNaoLogados.Count == 2)
                      break;
            }
            Console.ReadLine();
        }

 

Usando LINQ temos :

        static void Main(string[] args)
        {
            var usuarios = User.GetUsers();

            var usuariosNaoLogados = usuarios.Where(u => u.Ativo && u.Habilitado && !u.Logado).Take(2);
            Console.ReadLine();
        }

Muito mais simples...

3- Obtendo o primeiro elemento de uma coleção

Enfrentamos muitas situações em que temos que ler o primeiro elemento de uma coleção.

Começaríamos avaliando a coleção com null e então sua contagem de elementos e assim por diante. Agora, existe a possibilidade de que essa coleção esteja vazia.

Portanto, um exemplo de código clássico poderia ser o seguinte:

        static void Main(string[] args)
        {
            List<string> adminUsers = User.GetUserAdmin();
            string primeiroUsuario;

            if ((adminUsers != null) && (adminUsers.Count > 0))
            {
                primeiroUsuario = adminUsers[0];
            }

            Console.ReadLine();
        }

Usando LINQ teremos:

        static void Main(string[] args)
        {
            List<string> adminUsers = User.GetUserAdmin();
            var primeiroUsuario = adminUsers.FirstOrDefault();

            Console.ReadLine();
        } 

4- Inicializando arrays usando Loops

Em muitos cenários usamos loops para inicializar arrays, e, fazemos isso muitas vezes para escrever um código de teste rápido.

A seguir temos um exemplo típico deste uso:

        static void Main(string[] args)
        {
            int[] mesesNoAno = new int[12];
            for (int i = 0; i < mesesNoAno.Length; i++)
            {
                mesesNoAno[i] = i + 1;
            }
            Console.ReadLine();
        }     

Podemos usar LINQ e substituir esse código usando o método System.Linq.Enuemerable.Range :

        static void Main(string[] args)
        {
            int[] mesesNoAno = System.Linq.Enumerable.Range(1, 12).ToArray();

            Console.ReadLine();
        }

5- Substituindo dois Loops similares com Concat

Se você tiver que percorrer dois arrays de natureza semelhante, poderá usar a extensão Concat e escrever um código conciso.

No código abaixo estamos usando dois Loops para percorrer cada array:

        static void Main(string[] args)
        {
            StringBuilder todosElementos = new StringBuilder();
            int[] primeiroArray = System.Linq.Enumerable.Range(1, 10).ToArray();
            int[] segundoArray = System.Linq.Enumerable.Range(10, 10).ToArray();
            foreach (var pa in primeiroArray)
            {
                todosElementos.AppendLine(string.Format("{0}", pa));
            }
            foreach (var sa in segundoArray)
            {
                todosElementos.AppendLine(string.Format("{0}", sa));
            }
            Console.ReadLine();
        }

Usando LINQ podemos usar o método de extensão Concat para concatenar os dois arrays e usar um loop:

         static void Main(string[] args)
        {
            StringBuilder todosElementos = new StringBuilder();
            int[] primeiroArray = System.Linq.Enumerable.Range(1, 10).ToArray();
            int[] segundoArray = System.Linq.Enumerable.Range(10, 10).ToArray();
            foreach (var a in primeiroArray.Concat(segundoArray))
            {
                todosElementos.AppendLine(string.Format("{0}", a));
            }

            Console.ReadLine();
        }

Em outro artigo vamos continuar mostrando como melhorar o seu código com  LINQ.

Aguarde.

Pegue o projeto aqui:  LINQ_MelhorCodigo.zip

(Disse Jesus)"Eu sou a videira verdadeira, e meu Pai é o lavrador. Toda a vara em mim, que não dá fruto, a tira; e limpa toda aquela que dá fruto, para que dê mais fruto."
João 15:1,2


Referências:


José Carlos Macoratti