.NET - Apresentando e usando Métodos Genéricos (VB .NET) - II


 Neste artigo vou apresentar os conceitos e mostrar como podemos usar métodos genéricos na linguagem VB .NET.


Eu vou repetir aqui os conceitos já descritos na primeira parte deste artigo visto que eles são os mesmos para a linguagem VB .NET.

 

Assim se você chegou diretamente neste artigo veja na primeira parte os conceitos usando a linguagem C#.

 

O que são métodos genéricos ?

 

Um método genérico é um método que é declarado com parâmetros de tipo.

 

Os métodos tradicionais trabalham com parâmetros e retornos fortemente tipados, ou seja, a todo  momento conhecemos os tipos concretos dos argumentos que recebemos e dos valores que retornamos.


Assim, métodos genéricos têm parâmetros de tipo e proporcionam uma maneira de parametrizar os tipos utilizados em um método.

Isto significa que você pode fornecer uma implementação e pode chamar o método com tipos diferentes.


Métodos genéricos são uma forma poderosa de fornecer segurança de tipo e ainda criar métodos flexíveis que suportam vários tipos.

A ideia por trás de um método genérico é simples: um método genérico aceita parâmetros e retorna valores de uma gama de diferentes tipos.

 

Por isso, ele é chamado genérico.


A sintaxe usada para criar métodos genéricos pode parecer a primeira vista um tanto incomum. A forma de sintaxe para a declaração usa os caracteres <T> após o nome do método, mas antes da lista de parâmetro formal.

 

Nota: Todos os exemplos foram feitos no Visual Studio Express 2013 for Windows desktop.

 

Vejamos um exemplo:

 

Private Shared Sub Trocar(Of T)(ByRef lhs As T, ByRef rhs As T)

    Dim temp As T
    temp = lhs
    lhs = rhs
    rhs = temp

End Sub

 

Neste código temos a declaração do método genérico Trocar(Of T) que vai receber dois argumentos de quaisquer tipo e realizar a troca de valores entre os argumentos recebidos.

 

Podemos usar este método da seguinte forma:

 

Module Module1
    Sub Main()
        Dim a As Integer = 10
        Dim b As Integer = 20
        Trocar(Of Integer)(a, b)
        Console.WriteLine(a.ToString() + " " + b.ToString())
        Console.ReadKey()
        Dim x As String = "primeiro"
        Dim y As String = "segundo"
        Trocar(Of String)(x, y)
        Console.WriteLine(x.ToString() & " " & y.ToString())
        Console.ReadKey()
    End Sub
    Private Sub Trocar(Of T)(ByRef lhs As T, ByRef rhs As T)
        Dim temp As T
        temp = lhs
        lhs = rhs
        rhs = temp
    End Sub
End Module

 

Note que procuramos representar no código uma ideia conceitual do tipo : "Meu método vai receber dois objetos de um tipo T qualquer e vai  trocar os valores dos objetos"

Antes de mostrar outro exemplo de método genérico vamos definir um método tradicional que se propõe a fazer a mesma tarefa: Obter o valor máximo entre dois objetos.

Um código possível para realizar tal tarefa seria:

 Public Function Max(ByVal val1 As Double, ByVal val2 As Double) As Double
 
       Return IIf(val2 < val1, val1, val2)

 End Function

Qual o problema com o código acima ?

Nenhum, mas o método somente pode ser aplicado a tipos de dados Double.

Suponha que agora eu quero representar via código a seguinte ideia conceitual : "Meu método vai receber dois objetos de um tipo T que implemente a interface IComparable e vai retornar o maior deles"

Public Function Maximo(Of T As IComparable)(valor1 As T, valor2 As T) As T
        If valor1.CompareTo(valor2) > 0 Then
            Return valor1
        End If
        Return valor2
End Function

O método genérico Maximo<Of T> vai processar qualquer tipo T. Os parâmetros de entrada também são do tipo T e o retorno também e do tipo T.

A seguir temos um exemplo de como usar o método genérico criado acima:

Module Module1
    Sub Main()
        Dim maiorString As String = Maximo("Macoratti", "Jefferson")
        Dim maiorInteiro As Integer = Maximo(2, 99)
        Dim maiorDouble As Double = Maximo(445.98, 98.65)
        Console.WriteLine("Maior String  = {0} ", maiorString)
        Console.WriteLine("Maior Inteiro = {0} ", maiorInteiro.ToString())
        Console.WriteLine("Maior Double  = {0} ", maiorDouble.ToString())
        Console.ReadKey()
    End Sub
    Public Function Maximo(Of T As IComparable)(valor1 As T, valor2 As T) As T
        If valor1.CompareTo(valor2) > 0 Then
            Return valor1
        End If
        Return valor2
    End Function
End Module

Neste exemplo observe que temos uma restrição no método que diz que o tipo T deve implementar a interface IComparable().

Usando essa linha de raciocínio existem vários tipos de restrições que podem ser utilizadas para limitar os tipos permitidos para os nossos métodos parametrizados. Abaixo temos algumas delas:

Suponha que você queira restringir os tipos do método Trocar (que vimos no início do artigo) para tipos de estrutura não anuláveis.  Você pode adicionar uma restrição no Trocar para indicar que ele é aplicável somente aos tipos de valores (estruturas).

No código abaixo temos que o método Trocar agora é definido como sendo restrito a estruturas (ou tipos de valor).

    Public Sub Trocar(Of T As Structure)(ByRef a As T, ByRef b As T)
        Dim temp As T
        temp = a
        a = b
        b = temp
    End Sub

Para concluir vejamos agora um exemplo um pouco mais complexo. O método genérico CriaLista, aplicável a qualquer classe, retorna uma lista genérica (List(Of T)) do tipo parametrizado do método, inicialmente preenchida com os argumentos (variáveis) que são fornecidos:

  Public Function CriaLista(Of T)(ParamArray pars As T()) As List(Of T)
        Dim lista As New List(Of T)()
        For Each elem As T In pars
            lista.Add(elem)
        Next
        Return lista
    End Function

A seguir vamos usar este método:

Module Module1
    Sub Main()

        Dim numeros As List(Of Integer) = CriaLista(Of Integer)(1, 2, 3, 4, 6, 7)
        Dim nomes As List(Of String) = CriaLista(Of String)("Macoratti", "Jefferson", "Miriam", "Janice")

        For Each numero As Integer In numeros
            Console.WriteLine(numero.ToString() + " ")
        Next
        Console.ReadKey()
        For Each nome As String In nomes
            Console.WriteLine(nome & " ")
        Next
        Console.ReadKey()
    End Sub
    Public Function CriaLista(Of T)(ParamArray pars As T()) As List(Of T)
        Dim lista As New List(Of T)()
        For Each elem As T In pars
            lista.Add(elem)
        Next
        Return lista
    End Function
End Module

Sobrecarga de Métodos genéricos

Os métodos podem ser sobrecarregados com base em argumentos, mas não em tipos de retorno e métodos também podem ser sobrecarregados por tipos parametrizados.

Por exemplo, todos os seguintes métodos podem existir no mesmo escopo:

    Sub Teste()
    End Sub
    Sub Teste(ByVal s As String)
    End Sub

    Sub Teste(Of T)(ByVal arg As T)
    End Sub

    Sub Teste(Of T, U)(ByVal arg1 As T, ByVal arg2 As U)
    End Sub

Pegue o projeto completo aqui:  Metodos_Genericos_VBNET.zip

Quem ama a sua vida perdê-la-á, e quem neste mundo odeia a sua vida, guardá-la-á para a vida eterna.
Se alguém me serve, siga-me, e onde eu estiver, ali estará também o meu servo. E, se alguém me servir, meu Pai o honrará.

João 12:25,26

Quem ama a sua vida perdê-la-á, e quem neste mundo odeia a sua vida, guardá-la-á para a vida eterna.
Se alguém me serve, siga-me, e onde eu estiver, ali estará também o meu servo. E, se alguém me servir, meu Pai o honrará.
João 12:25,26
Quem ama a sua vida perdê-la-á, e quem neste mundo odeia a sua vida, guardá-la-á para a vida eterna.
Se alguém me serve, siga-me, e onde eu estiver, ali estará também o meu servo. E, se alguém me servir, meu Pai o honrará.
João 12:25,26
Quem ama a sua vida perdê-la-á, e quem neste mundo odeia a sua vida, guardá-la-á para a vida eterna.
Se alguém me serve, siga-me, e onde eu estiver, ali estará também o meu servo. E, se alguém me servir, meu Pai o honrará.
João 12:25,26
Quem ama a sua vida perdê-la-á, e quem neste mundo odeia a sua vida, guardá-la-á para a vida eterna.
Se alguém me serve, siga-me, e onde eu estiver, ali estará também o meu servo. E, se alguém me servir, meu Pai o honrará.
João 12:25,26
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 ?

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti