.NET - Usando Generics
A versão 2.0 da plataforma .NET introduziu as coleções genéricas que ficam agrupadas no namespace System.Collections.Generics; Generics permite a definição de tipos em tempo de execução. |
Podemos dizer que Generics são coleções tipadas de modo que somente um tipo de dado pertença a coleção. Ao se tentar inserir outro tipo de dado o compilador irá reclamar. Assim sabemos o que cada coleção contém e não precisamos fazer a conversão na hora de retirar um item da coleção.
Estas coleções Generics são fortemente tipadas, ou seja, estão disponíveis no intelissense e são verificadas pelo compilador, o que evita erros e torna mais fácil a vida do desenvolvedor.
Os problemas que envolvem o uso de coleções no VB.NET podem ser resumidos da seguinte forma:
|
As principais coleções genéricas são:
List(Of T) - Representa uma lista fortemente tipada de objetos que podem ser acessados através de um índice. Fornece os métodos Search, Sort e efetua a manipulação da lista.
LinkdeList(Of T) - Organiza os itens na forma de uma lista duplamente ligada.
Stack(Of T) - Organiza os itens na forma de um pilha.(LIFO - last-in first-out)
SortedList(Of TKey, TValue) - Representa uma coleção de pares representados por chave/valor que são ordenados pela chave com base na implementação de System.Collections.Generic.IComparable associada.
SortedDictionary(Of TKey, TValue) - Representa uma coleção de pares representados por chave/valor que são ordenados pela chave.
Queue(Of T) - Organiza os itens na forma de uma fila.(FIFO - first-in firs-out)
Nota: O parâmetro (Of T) na declaração da lista é obrigatório e indica qual o tipo de dados que poderá ser incluído na coleção.
Começando pelo começo
Um das coleções genéricas mais usada é a List(Of (T)), onde se define o tipo da coleção que se pretende usar.
Vamos iniciar um exemplo bem simples definindo uma lista do tipo String:
Abra o Visual Basic 2008 Express Edition e crie um novo projeto do tipo Windows Application com o nome usandoGenerics;
Inclua os seguintes controles no formulário: ListBox (lstALunos) , TextBox (txtNome) e Button1 (btnProcurar) e Button2(btnListar) conforme o leiaute abaixo:
No formulário padrão form1.vb no início da classe Form1 vamos declarar uma lista do tipo String:
' Cria uma nova
lista do tipo "string"
Dim listaAlunos As New List(Of String)
Onde List(Of T) repesenta uma lista fortemente tipada que pode ser acessada pelo índice e fornece métodos para ordernar, procurar e manipular listas.
No evento Load do formulário vamos popular a lista com nomes:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Inclui nomes na lista listaAlunos.Add("Macoratti") listaAlunos.Add("Jefferson") listaAlunos.Add("Jessica") listaAlunos.Add("Janice") listaAlunos.Add("Bianca") listaAlunos.Add("Yuri") listaAlunos.Add("Larissa") listaAlunos.Add("Larissa") listaAlunos.Add("Madalena") listaAlunos.Add("Marcia") listaAlunos.Add("Carlos") End Sub |
Agora no evento Click do botão de comando inclua o seguinte código:
Private Sub btnProcurar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExibir.Click Dim nomeAluno As String = txtNome.Text ' Encontrou o nome If listaAlunos.Contains(nomeAluno) Then ' Exibe o nome e o total de nomes Dim msg As String = "{0} foi encontrado em uma relação de {1} nome(s)" lstAlunos.Items.Add(String.Format(msg, nomeAluno, listaAlunos.Count)) Else ' Não encontrou nome na lista lstAlunos.Items.Add("Nome não encontrado na lista!") End If End Sub |
Neste código usamos os seguintes métodos da lista :
Para listar o conteúdo da lista incluimos o código abaixo no evento Click do botão Listar:
Private Sub btnListar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnListar.Click For i = 0 To listaAlunos.Count - 1 lstAlunos.Items.Add(listaAlunos(i)) Next End Sub |
Como alternativa para listar o conteúdo de uma lista tipada podemos também usar os seguintes métodos:
For Each nome As String In listaAlunos lstAlunos.Items.Add(nome) Next |
Usando o loop For Each percorremos a lista e exibimos o nome. |
ou ainda:
Dim atual As String Dim en As IEnumerator(Of String) = listaAlunos.GetEnumerator() While (en.MoveNext()) atual = en.Current lstAlunos.Items.Add(atual) End While |
Usando o GetEnumerator()
que é um função da interface IEnumerable obtemos um enumerator com qual podemos percorrer a coleção usando a função MoveNext(). Quando usamos o MoveNext()
o enumerator vai para a primeira Ao chegar ao final da
coleção para retornar usamos a propriedade |
Se você desejar ordernar a lista basta usar a função Sort: listaAlunos.Sort()
Se Desejar passar os nomes da lista para caixa baixa use o método ToLower. Quer caixa alta então use a função ToUpper.
No exemplo abaixo usamos as funções Sort para ordernar e ToUpper para colocar em caixa alta os nomes da lista:
Dim atual
As String listaAlunos.Sort() Dim en As IEnumerator(Of String) = listaAlunos.GetEnumerator() While (en.MoveNext()) atual = en.Current.ToUpper() lstAlunos.Items.Add(atual) End While |
Com o advento do Generics podemos usar um código mais limpo e otimizado em nossas aplicações que tratam com coleções de dados como as aplicações que usam Banco de dados Relacionais.
Neste caso podemos criar uma classe definindo um tipo de dados para a nossa entidade e depois definir uma lista genérica do tipo da classe que implementamos. Entendeu ??? Bem, vamos mostrar isso na prática...
Neste exemplo eu vou criar uma aplicação ASP .NET usando a linguagem VB .NET que terá como objetivo acessar a tabela Alunos em um banco de dados SQL Server Express Edition. (Vou usar a versão 2005) e exibir a relação de alunos em uma página web.
Até nada de mais , você pode estar pensando. A novidade é que eu vou usar generics para obter uma lista dos alunos que estão na tabela Alunos. Vejamos...
Abra o Visual Web Developer 2008 Express Edition e crie um novo web site usando o template ASP .NET Web Site com o nome listaAlunosGenerics;
A seguir clique no menu Web Site e selecione a opção Add new Item e na janela Templates selecione o template SQL Server DataBase, informe o nome Escola.mdf e clique em Add;
Clique no botão Sim para salvar o banco de dados na pasta App_Data:
A seguir abra o banco de dados na janela DataBase Explorer e crie a tabela Alunos com a seguinte estrutura:
Clique com o botão direito do mouse sobre a tabela criada , selecione a opção Show Table Data e inclua alguns registros na tabela.
Selecione a página Default.aspx e inclua um componente GridView com id=gdvAlunos na página:
Agora vamos criar uma classe que representará a nossa tabela Alunos como uma entidade. Para isso no menu Web Site selecione Add New Item e em templates selecione Class e informe o nome Aluno.vb e clique em Add;
Confirme a opção para salvar o arquivo na pasta App_Code;
Define o código abaixo no arquivo Alunos.vb:
Public Class Aluno Dim _id As Long Dim _nome As String Dim _email As String ReadOnly Property ID() As Long Get Return _id End Get Set(ByVal value As Long) _id = value End Set End Property Property Nome() As String Get Return _nome End Get Set(ByVal value As String) _nome = value End Set End Property Property Email() As String Get Return _email End Get Set(ByVal value As String) _email = value End Set End Property End Class |
|
O código define 3 membros e 2 propriedades para a classe Aluno que representa um aluno com id , nome e email.
Agora só resta criar o código no arquivo code-behind Default.aspx.vb para acessar o banco de dados obter os registros e gerar a lista genérica usando a classe Aluno como tipo.
Abra o arquivo code-behind Default.aspx.vb e inclua o código abaixo:
Imports usados:
Imports
System.Data
Imports System.Data.SqlClient
O método getAlunos() que acesso o banco de dados e gera uma lista
contendo uma coleção de objetos do tipo Aluno:
Private Function getAlunos() As List(Of Aluno) Dim strConn As String = "Data Source=.\SQLEXPRESS;AttachDbFilename= C:\_aspn\listaAlunosGenerics\App_Data\Escola.mdf;Integrated Security=True;User Instance=True" Dim sql As String = "Select * from Alunos" Dim listaAlunos As List(Of Aluno) = New List(Of Aluno) Dim con As SqlConnection = New SqlConnection(strConn) Try Dim cmd As SqlCommand = New SqlCommand(sql, con) con.Open() Dim dr As SqlDataReader = cmd.ExecuteReader While (dr.Read) Dim aluno As New Aluno aluno.ID = dr("id") aluno.Nome = dr("nome") aluno.Email = dr("email") listaAlunos.Add(aluno) End While Return listaAlunos Catch Throw New Exception("Erro ao gerar lista de alunos") Finally con.Close() End Try End Function |
No evento Load da página Default.aspx inclua o código que irá usar a função getAlunos():
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load gdvAlunos.DataSource = getAlunos() gdvAlunos.DataBind() End Sub |
Executando a página iremos obter o seguinte resultado:
Mas afinal qual a vantagem ? Ora bolas, com Generics estamos trabalhando com objetos fortemente tipados em lista de coleções de objetos e ao invés de passar um dataset ou datatable estamos trafegando objetos.
Pegue os projetos completos aqui: UsandoGenerics.zip (VB .NET) listaAlunosGenerics.zip (ASP .NET)
Eu sei é apenas VB .NET e Generics, mas eu gosto...
Referências:
José Carlos Macoratti