Generics do .Net 2.0
Trabalhando com códigos genéricos em C# e VB.Net

por Laércio Queiroz

Veremos neste artigo como escrever classes e métodos génericos em C# e VB.Net. Este recurso não é específico das linguagens, sendo assim, esta técnica pode ser implementada com as outras linguagens suportadas pelo .Net Framework v.2.0.

Generics?

Com o passar do tempo e o aumento da complexidade que envolve o desenvolvimento das aplicações, os programadores precisam cada vez mais, reutilizar e estender os códigos já existentes (evitando "recriar a roda"). Com esse propósito, foi adicionado ao .Net v.2.0, uma técnica chamada Generics.

Como as técnicas de POO, usando Generics nós podemos produzir códigos mais eficientes e flexiveis. Esta técnica nos permite criar modelos de código que se ajuste a vários tipos. Quando queremos criar uma instância de uma classe com esta característica, deveremos transforma-la em uma "classe tipada", informando qual tipo desejamos manipular. O compilador faz uma validação do tipo declarado, a fim de evitar erros de incompatibilidade em tempo de execução. Observe os exemplos abaixo a declaração de uma classe genérica:

VB.Net - Declarando uma classe genérica:

Public Class GenericClass(Of MeuTipo)
 'Código da classe.
End Class


C# - Declarando uma classe genérica:

public class GenericClass
{
 //Código da classe.

}

Agora criaremos um objeto do tipo ArrayList e vamos adicionar dois métodos (Adicionar e Remover) em nossa classe GenericClass. Codifique os métodos como descrito abaixo:

VB.Net - Implementando a classe GenericClass:

Public Class GenericClass(Of MeuTipo)
 Dim oList As New ArrayList()

 Public Sub Adicionar(ByVal value As MeuTipo)
   oList.Add(value)
 End Sub

 Public Sub Remover(ByVal value As MeuTipo)
   oList.Remove(value)
 End Sub
End Class


C# - Implementando a classe GenericClass:

public class GenericClass
{
 ArrayList oList = new ArrayList();
 
 public void
Adicionar(MeuTipo value)
 {
  oList.Add(value);
 }
 
 public void Deletar(MeuTipo value)
 {
  oList.Remove(value);
 }
}

Observe que na declaração dos métodos os parâmetros passados são do mesmo tipo declarado no início da classe. Isso reforça a idéia de que o classe genérica será tipada no momento da instância do objeto. Para exemplificarmos melhor, observe a utilização da classe no código abaixo:

VB.Net - Criando uma instância de GenericClass:

 'Criando uma instância e tipando a classe.
 Dim MyList As New GenericClass(Of Integer)

 'Adicionando dois elementos inteiros.

 MyList.Adicionar(340)
 MyList.Adicionar(120)

 'Este procedimento deve gerar um erro.
 MyList.Adicionar("Laércio")


C# - Criando uma instância de GenericClass:

 //Criando uma instância e tipando a classe.
 GenericClass MyList = new  GenericClass;

 //Adicionando dois elementos inteiros.

 MyList.Adicionar(340);
 MyList.Adicionar(120);

 //Este procedimento deve gerar um erro.
 MyList.Adicionar("Laércio");

O último procedimento deve gerar um erro pois estamos tentando adicionar a uma lista de inteiros - definido na instância do objeto, um valor do tipo string. Para que nossa classe possa manipular mais de um tipo, devemos declarar a classe como no exemplo abaixo:

VB.Net - Manipulando tipos diferentes:

Public Class GenericClass(Of String, Integer)
 'Código da classe.
End Class


C# - Manipulando tipos diferentes:

public class GenericClass <string, integer>
{
 //Código da classe.

}

Constraints

As constraints (restrições) são critérios utilizados para especificar algumas características dos parâmetros de tipo da nossa classe genérica. Observe os exmplos de algumas dessas especificações descritas abaixo:

C# - O tipo passado como parâmetro deve implementar a interface IEnumerable.

public class GenericClass
where MeuTipo : IEnumerable
{
 //Código da classe.

}

Separando as condicionais:
public class GenericClass
where MeuTipo : IEnumerable,
MeuTipo: IDisposable
{
 //Código da classe.

}

VB.Net - O tipo passado como parâmetro deve implementar a interface IEnumerable.

Public Class GenericClass(Of MeuTipo As IEnumerable)
 'Código da classe
End Class

Separando as condicionais:
Public Class GenericClass(Of MeuTipo As IEnumerable, IDisposable)
 'Código da classe
End Class

C# - O tipo passado deve ter um construtor padrão público.

public class GenericClass
where MeuTipo : new()
{
 //Código da classe.

}


VB.Net - O tipo passado deve ter um construtor padrão público.

Public Class GenericClass(Of MeuTipo As New)
 'Código da classe
End Class

Conclusão

Vimos neste artigo como tirar proveito desta nova funcionalidade do Framework 2.0, e como nós programadores podemos facilitar o nosso trabalho, escrevendo o código uma vez e usando muitas. Mais informações sobre Generics você pode encontrar em sites como MSDN.com e ONDotNet.com. Até a próxima! e fique ligado no Portal Web Mobile.