VB .NET - Consultando tipos não Genéricos usando LINQ


 Neste artigo vou mostrar como consultar tipos não genéricos com LINQ usando a linguagem VB .NET.

O recurso Generics foi introduzido no .NET Framework 2.0. Antes disso, o namespace System.Collections possuía coleções que podiam armazenar objetos.

Com o advento do Generics um monte de classes de coleção adotaram o recurso e implementaram a interface IEnumerable(Of T).

No entanto, existem outros tipos não genéricos que não suportam as versões genéricas de IEnumerable mas apenas a sua versão não genérica.

O LINQ pode ser usado para consultar objetos que são coleções genéricas que implementam a interface IEnumerable(Of T). 

No entanto coleções não genéricas, como o ArrayList não implementam a interface IEnumerable(Of T) e não dão suporte a consultas LINQ pois os métodos de extensão que compõem as cláusulas de consulta padrão não estendem de IEnumerable.

Supondo uma coleção de nomes que implementa a interface IEnumerable(Of T) chamada Nomes a consulta LINQ seria feita assim:

Dim consulta = From nome in Nomes

Mas se a coleção for um ArrayList a consulta pode não ser executada de forma correta porque nome não é fortemente tipado.

Vamos ver então como podemos realizar consultas LINQ usando coleções não genéricas.

Recursos usados:

Nota: Baixe e use a versão Community 2015 do VS ela é grátis e é equivalente a versão Professional.

Criando o projeto no VS Community

Abra o VS Community 2015 e clique em New Project;

Selecione a linguagem Visual Basic e o template Windows Forms Application

Informe o nome Consultas_LINQ_ColecaoNaoGenerica e clique no botão OK;

No formulário form1.vb inclua os seguintes controles:

Disponha os controles no formulário conforme o leiaute da figura abaixo:

Agora no menu Project clique em Add Class e informe o nome Carro.

Inclua o código abaixo no arquivo Carro.vb:

Public Class Carro
    Public Property Fabricante As String
    Public Property Modelo As String
    Public Property Ano As Integer
End Class

Agora vamos definir uma variável chamada listaDeCarros do tipo ArrayList no início do formulário:

Dim listaDeCarros As ArrayList

A seguir no evento Click do botão de comando - Carregar Coleção Não Genérica -  inclua o código a seguir nesta classe :
 Private Sub btnCarregarColecao_Click(sender As Object, e As EventArgs) Handles btnCarregarColecao.Click
        listaDeCarros = New ArrayList()
        listaDeCarros.Add(New Carro With {.Fabricante = "Ford", .Modelo = "Fiesta", .Ano = 2009})
        listaDeCarros.Add(New Carro With {.Fabricante = "Fiat", .Modelo = "Uno", .Ano = 2012})
        listaDeCarros.Add(New Carro With {.Fabricante = "Renault", .Modelo = "Sandero", .Ano = 2013})
        listaDeCarros.Add(New Carro With {.Fabricante = "Fiat", .Modelo = "Siena", .Ano = 2014})
        listaDeCarros.Add(New Carro With {.Fabricante = "VolksWagen", .Modelo = "Gol", .Ano = 2008})
        listaDeCarros.Add(New Carro With {.Fabricante = "Honda", .Modelo = "Fit", .Ano = 2010})
        listaDeCarros.Add(New Carro With {.Fabricante = "VolksWagen", .Modelo = "Fox", .Ano = 2009})
        listaDeCarros.Add(New Carro With {.Fabricante = "Renault", .Modelo = "Duster", .Ano = 2013})
        dgvCarros.DataSource = listaDeCarros
        btnConsulta1.Enabled = True
        btnConsulta2.Enabled = True
        btnConsulta3.Enabled = True
        btnCarregarColecao.Enabled = False
 End Sub

Vamos entender o código:

Criamos uma instância de listaDeCarros e incluímos alguns dados da classe Carro no ArrayList.

Agora para realizar as consultas vamos usar os 3 botões de comando:

1 - Declarar o Tipo da variável explicitamente

Quando usamos LINQ com coleções não genéricas, como um ArrayList, precisamos declarar explicitamente o tipo da variável para refletir o tipo especifico do objetos na coleção:

Neste exemplo estamos declarando explicitamente o tipo Carro na consulta:

   Private Sub btnConsulta1_Click(sender As Object, e As EventArgs) Handles btnConsulta1.Click
   
     Dim consulta1 = From carro As Carro In listaDeCarros
                               Where carro.Fabricante = "Fiat"
                               Select carro
        dgvDados.DataSource = consulta1.ToList
    End Sub

2 - Usar o operador Cast

Outra opção para usar LINQ com coleções não genéricas, como um ArrayList, é usar o operador Cast que toma uma coleção não genérica e retorna um IEnumerable(Of T).

Neste exemplo estamos declarando explicitamente o tipo Carro na consulta:

   Private Sub btnConsulta1_Click(sender As Object, e As EventArgs) Handles btnConsulta1.Click
   
         Dim consulta1 = From carro In listaDeCarros.Cast(Of Carro)
                                  Where carro.Modelo.StartsWith("F")
                                  Select carro
        dgvDados.DataSource = consulta1.ToList
  End Sub

3 - Usar o operador OfType

Podemos também usar o operador OfType que filtra os elementos de um IEnumerable baseado em um tipo específico. Assim se você tiver diferentes tipo em seu ArrayList você obterá somente o tipo consultado:

   Private Sub btnConsulta1_Click(sender As Object, e As EventArgs) Handles btnConsulta1.Click
   
     Dim consulta1 = From carro In listaDeCarros.OfType(Of Carro)
                                Where carro.Ano > 2010
                               Select carro
        dgvDados.DataSource = consulta1.ToList
    End Sub

Executando o projeto e executando uma consulta iremos obter o seguinte resultado:

Pegue o projeto completo aqui :  Consultas_LINQ_ColecaoNaoGenerica.zip

"Bendito o Deus e Pai de nosso Senhor Jesus Cristo, o qual nos abençoou com todas as bênçãos espirituais nos lugares celestiais em Cristo;"
Efésios 1:3

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