Desenvolvimento - Visual Basic .NET

Usando generics no Visual Basic.Net 2005

Uma das grandes novidades da versão 2.0 do .Net framework é a inclusão de generics, que, por ser muito útil, certamente fará parte do dia-a-dia dos programadores .Net.

por Rodrigo Vieira



1) ArrayList é ótimo, porém limitado

Uma das grandes novidades da versão 2.0 do .Net framework é a inclusão de generics, que, por ser muito útil, certamente fará parte do dia-a-dia dos programadores .Net

Talvez a forma mais fácil de vermos o que são generics e como utilizá-los seja analisando de onde surgiu a necessidade dessa nova funcionalidade, a partir da versão 1.0/1.1 do .Net Framework.

Vamos então comecar analisando a classe ArrayList, bem conhecida por todos programadores .Net: essa classe permite que criemos listas de objetos, e apresenta uma série de funções para adicionar, remover e analisar o conteúdo das mesmas. Suponha que nosso programa tenha uma classe chamada "Pessoa", com as propriedades "ID", "Nome" e "Email", da seguinte forma *:

Public Class Pessoa

    Private _id as Integer
    Private _nome As String
    Private _email As String

    Public ReadOnly Property ID() As Integer
        Get
            Return _id
        End Get
    End Property

    Public Property Nome() As String
        Get
            Return _nome
        End Get
        Set(ByVal value As String)
            _nome = value
        End Set
    End Property

    Public Property Email() As String
        Get
            Return _email
        End Get
        Set(ByVal value As String)
            _email = value
        End Set
    End Property

End Class

Agora poderíamos criar uma instância da classe Pessoa, e armazená-lo em um ArrayList, da seguinte forma:

Repare que o código, ainda que funcione bem, tem uma limitação: o método "Add" do ArrayList aceita qualquer objeto, então nada me impediria que eu fizesse algo do tipo

Um outro problema é que não podemos usar intelissense quando usamos ArrayLists dessa forma, ou seja, quando digitamos...

...não vemos as propriedades da classe Pessoa, tais como Nome e Email, o que torna a programação menos produtiva.

Um terceiro problema relacionado ao uso de ArrayLists é que ao manipularmos elementos do mesmo, ocorrem conversões implícitas (por exemplo, um valor do tipo Integer é convertido em um objeto ao ser adicionado), o que pode causar um impacto no desempenho da aplicação.

Problemas como os mencionados acima são comuns e muitas vezes só são detectados quando o programa é entregue, já que nenhum erro de compilação é gerado. É pra melhorar essa situação (entre várias outras coisas) que foi introduzido o conceito de generics. 2) Utilizando generics

Vamos então reimplementar a nossa coleção "pessoas" usando generics: antes de mais nada, precisamos adicionar um comando "Import" no topo do código, para termos fácil acesso a todas as classes relacionadas a Generics:

Imports System.Collections.Generic

E então poderíamos mudar a declaração da coleção, de ArrayList para System.Collections.Generic.List:

Dim pessoas As New List(Of Pessoa)

Repare que colocamos o parâmetro "Of Pessoa" na declaração da lista: esse parâmetro é obrigatório, e informa qual o tipo de dados que poderá ser incluído na lista. Enquanto um ArrayList aceitaria qualquer objeto, nossa nova lista aceita a partir de agora apenas itens do tipo "Pessoa". Caso tentássemos colocar o valor "string" em um desses itens, como fizemos anteriormente, veríamos uma mensagem de erro já no editor, e também na compilação:

A partir do momento que declaramos a coleção com generics, também temos acesso ao intelissense em seus itens:

Essas são as vantagens mais óbvias de generics, e, embora sejam simples de se utilizar, evitam uma série de erros de programação, ao restringir e checar em tempo de codificação os tipos de dados utilizados. Isso por si só já justificaria o uso desse novo conceito, mas generics vão muito além disso. Podemos por exemplo criar nossas próprias classes que possuam suporte a generics, conforme veremos a seguir.

3) Outras utilidades para generics

Suponha, por exemplo, que eu queira criar um "cache" de objetos em meu sistema, ou seja, armazenar objetos na memória depois de carregados do banco de dados, para que possam ser reutilizados sem novo acesso ao disco.

Eu poderia então definir minha classe assim:

Public Class ObjectCache(Of ItemType)
    Inherits Generic.Dictionary(Of Integer, ItemType)

    "aqui definimos os metodos do nosso cache...
End Class

Note que eu coloquei a instrução "Of ItemType" na declaração da classe, ou seja, quando o usuário for criar uma instância do ObjectCache, terá que informar que tipo de dados esse cache lidará, da mesma forma que ocorre com os objetos do tipo Generic.List da seção anterior. Também herdamos a classe genérica Dictionary, já que acessaremos os itens do cache através de sua chave.

Quando utilizarmos o cache em nosso programa, observaremos algo interessante:

Veja que ao declararmos o nosso objeto OC com o tipo Pessoa na primeira linha, o mesmo só aceitará objetos desse tipo ao utilizarmos o comando "Add". Analogamente, ao buscarmos itens em nosso cache, o mesmo será especificamente dessa classe Pessoa:

Em outra parte do programa eu poderia criar um outro cache, dessa vez para objetos do tipo "Empresa":

E dessa forma, não existe a possibilidade do usuário colocar objetos do tipo Pessoa no cache de empresas, ou vice-versa, pois os mesmos gerariam erros de compilação.

Bem, acredito que isso seja um bom começo! Generics possuem muito mais detalhes interessantes, e esse artigo cobriu apenas a ponta do iceberg, mas espero que tenha sido suficiente para mostrar por que generics valem a pena serem amplamente utilizados para melhorar a qualidade dos seus programas.

Boa sorte!

(*) Os exemplos acima foram desenvolvidos utilizando a ferramenta "Visual Web Developer 2005 (Beta)", que suporta a versão 2.0 do framework, e pode ser baixado livremente no site da Microsoft.

Rodrigo Vieira

Rodrigo Vieira - MCSD e MCAD, formado em Ciência da Computacão, trabalhando há 5 anos em uma empresa de telecomunicacões em Oslo, Noruega, desenvolvendo aplicativos para Intranet nas plataformas .Net e Oracle. Entusiasta de Python, Mono, Linux e software livre em geral.
Blog The Spoke:
http://br.thespoke.net/MyBlog/rodviking/MyBlog.aspx