Desenvolvimento - C#

Usando o LINQ em Coleções não-genéricas

O LINQ tem sido encarado como o messias que irá livrar os desenvolvedores dos diversos problemas relacionados a busca de informações. O grande ponto é que o LINQ foi feito para trabalhar somente com coleções genéricas. Neste artigo veremos como utilizar o LINQ em coleções não-genéricas.

por Rodrigo Moreira



Obs: Apesar de o assunto abordado ser o LINQ, este artigo parte do pressuposto que o leitor já conhece o suficiente da tecnologia para criar suas expressões em sintaxe de query e usá-las em sua maneira habitual.

Não há dúvidas que LINQ é o assunto mais pop do mundo .net na atualidade. Parte integrante do novíssimo framework 3.5 e responsável pela maioria das mudanças nas novas versões das linguagens do mesmo, o LINQ tem sido encarado como o messias que irá livrar os desenvolvedores dos diversos problemas relacionados a busca de informações. O grande ponto, que nem sempre é abordado pelos artigos, é que o LINQ foi feito para trabalhar somente com coleções genéricas, ou seja, classes que implementam IEnumerable<T>, devido ao fato dos métodos do LINQ (como o Where) esperarem um parâmetro (geralmente chamado "source") do tipo IEnumerable<T> para que possam navegar item-a-item da coleção em questão seguindo as regras específicas do Enumerator correspondente. O grande problema com as coleções não-genéricas (Que implementam IEnumerable, ao invés de IEnumerable<T>) é que cada item será considerado um "object" tornando inacessíveis os membros específicos da classe. Dessa maneira, a solução é indicar o tipo de cada item da coleção, para que as devidas conversões possam ocorrer internamente. Esta indicação pode ser feita de três formas:

1) Indicar o tipo na própria expressão de query, como demonstrado na marcação abaixo:



2) Utilizar o extension method Cast<T>, criando uma coleção genérica com cada um dos itens convertidos para o tipo T:



3) Utilizar o extension method OfType<T>, o que incluirá na busca apenas os elementos do tipo T presentes na coleção.



Existem algumas diferenças que devem ser observadas na escolha da solução. As alternativas 1 e 2 são idênticas, porém com sintaxe diferentes, ou seja, quando você inclui o tipo na expressão de query (solução 1), internamente o método Cast<T> será chamado. A diferença entre a solução 2 e 3 é que, enquanto a solução 2 tenta converter cada item da coleção para o tipo desejado (o que pode resultar em uma InvalidCastException), a solução 3 executa a query somente nos itens do tipo informado, ignorando os demais e evitando assim as conversões inválidas.
Rodrigo Moreira

Rodrigo Moreira - Arquiteto de Software, trabalha com .net há mais de 5 anos e possui certificações Microsoft tanto na versão 1.x quanto 2.0 do .net framework (MCP e MCPTS). É Microsoft Student Partner Co-Lead, apaixonado pelo mundo de segurança no desenvolvimento de software e mantém o blog http://jackflashspot.spaces.live.com, onde escreve sobre seus devaneios no mundo do Software, além de seu trabalho como Microsoft Student Partner.