LINQ Series – Parte 1



 

Na primeira
parte desta série
, fizemos uma breve introdução ao Linq e vimos como preparar
o ambiente de desenvolvimento para começarmos a trabalhar com essa maravilhosa tecnologia.
Gostaria de, nesta, que chamo “parte 1”, fazer um pequeno exercício de compreensão
que, acredito, possa ser esclarecedor de algumas das motivações do Linq. Então, vamos
à questão: como você faria para escrever no console todos os números pares existentes
em um array de inteiros qualquer?



 

Acredito
que a resposta mais básica e simplória para essa questão – embora claramente válida
– é a utilização de um loop for (ou foreach) que iteraja por todos os elementos do
array, teste cada um deles para verificar se é par e, caso positivo, escreva-o no
console. O código abaixo mostra como isso pode ser feito:

 >

 

            int[]
numbers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };



 

            foreach (int number in numbers)

            {

                if (number
% 2 == 0)
Console.WriteLine(number);

            }

 

Este
código é perfeitamente válido para as versões 1.1 e 2.0 do Framework .NET e cumpre
a tarefa proposta. Mas vamos tentar mudar um pouco o foco procedural e iterativo do
código acima para algo mais declarativo. O que isso quer dizer? Teria alguma forma
de tormarmos mais clara a intenção desse nosso código? Vamos explorar um método introduzino
na classe Array no .NET 2.0 chamado ForEach<T>.



 

            int[]
numbers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };



 

            Array.ForEach

            (

                numbers,

                delegate(int number)

                {

                    if (number
% 2 == 0)
Console.WriteLine(number);

                }

            );



 

O
método Array.ForEach<T>() é um método genérico estático que pode ser usado em
arrays de qualquer tipo. Veja como a assinatura deste método está definida na classe
System.Array:



 

public static void ForEach<T>(T[]
array,
Action<T>
action);



 

O
tipo Action<T>, no segundo parâmetro, é um delegate definido da seguinte forma:



 

public delegate void Action<T>(T
obj);


 

O
método ForEach iterage por todos os elementos do array passado e, para cada elemento,
chama o método referenciado pelo delegate passando o elemento como argumento para
este método. Simplificando, o método referenciado pelo delegate será chamado para
cada item do array.



 

No
nosso exemplo, o delegate é definido anonimamente, ou seja, não foi criado um método
separado para esta finalidade. O código a ser executado foi simplesmente passado para
a operação ForEach. Este recurso, chamado Anonymous Delegates, foi introduzido no
.NET 2.0 e é um dos grandes habilitadores do design do Linq, como veremos em posts
futuros.



 

Embora
o recurso de anonymous delegates seja extremantente intessante, o código acima parece
ter ficado muito mais obscuro do que o código que utilizava o loop foreach tradicional.
Por conta disso, vamos dar um passo à frente e verificar como este código poderia
ser escrito usando o recurso de linguagem de consulta integrada (Linq – Language Integrated
Query), que será incorporado ao C# 3.0 e ao VB 9:



 

                int[]
numeros = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };



 

                IEnumerable<int>
numerosPares =
from numero in numeros

                                                where numero
% 2 == 0

                                                select numero;



 

                foreach (int par in numerosPares)

                {

                    Console.WriteLine(par);

                }



 

Embora
tenhamos escrito mais linhas do que no código original, a semântica de manipulação
de conjuntos proporcionada pela query Linq deixa claro que estamos consultando os
números pares de um conjunto original (array numbers). O resultado da query é mantido
em uma variável do tipo do tipo IEnumerable<int> denominada numerosPares. Para
escrever esses números no console, simplesmente usamos uma construção foreach tradicional.



 

O
código acima pode ser digitado em qualquer projeto que utilize um dos templates de
projeto do LINQ Preview, como vimos na parte
anterior desta série
. Na realidade, o código é dependente do assembly System.Query.dll,
que é referenciado automaticamente quando usamos um desses templates.



 

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>