Delegados (Visual Basic)

Os delegados são objetos que se referem aos métodos. Por vezes são descritos como ponteiros de função tipo seguro porque são semelhantes aos ponteiros de função utilizados noutras linguagens de programação. Mas, ao contrário dos ponteiros de funções, Visual Basic delegados são um tipo de referência baseado na classeSystem.Delegate. Os delegados podem referenciar ambos os métodos partilhados — métodos que podem ser chamados sem uma instância específica de uma classe — e métodos de instância.

Delegados e Eventos

Os delegados são úteis em situações em que é necessário um intermediário entre um procedimento de chamada e o procedimento que está a ser chamado. Por exemplo, você pode querer que um objeto que eleve eventos para ser capaz de chamar diferentes manipuladores de eventos em diferentes circunstâncias. Infelizmente, o objeto que eleva os eventos não pode saber com antecedência qual o manipulador de eventos que está a lidar com um evento específico. Visual Basic permite-lhe associar dinamicamente os manipuladores de eventos com eventos, criando um delegado para si quando utilizar a AddHandler declaração. No tempo de execução, o delegado remete as chamadas para o responsável pelo evento apropriado.

Embora possa criar os seus próprios delegados, na maioria dos casos Visual Basic cria o delegado e cuida dos detalhes por si. Por exemplo, uma Event declaração define implicitamente uma classe de delegado nomeada <EventName>EventHandler como uma classe aninhada da classe contendo a Event declaração, e com a mesma assinatura do evento. A AddressOf declaração cria implicitamente um caso de um delegado que se refere a um procedimento específico. As duas linhas de código seguintes são equivalentes. Na primeira linha, vê-se a criação explícita de um exemplo de EventHandler, com uma referência ao método Button1_Click enviado como argumento. A segunda linha é uma forma mais conveniente de fazer a mesma coisa.

AddHandler Button1.Click, New EventHandler(AddressOf Button1_Click)
' The following line of code is shorthand for the previous line.
AddHandler Button1.Click, AddressOf Me.Button1_Click

Pode utilizar a forma abreviada de criar delegados em qualquer lugar que o compilador possa determinar o tipo do delegado pelo contexto.

Declarando eventos que usam um tipo de delegado existente

Em algumas situações, pode querer declarar um evento para usar um tipo de delegado existente como seu delegado subjacente. A seguinte sintaxe demonstra como:

Delegate Sub DelegateType()
Event AnEvent As DelegateType

Isto é útil quando pretende encaminhar vários eventos para o mesmo manipulador.

Variáveis e Parâmetros delegados

Pode utilizar delegados para outras tarefas relacionadas com o evento, como a rosca livre ou com procedimentos que precisam de chamar diferentes versões de funções no tempo de execução.

Por exemplo, suponha que você tem uma aplicação de anúncios classificados que inclui uma caixa de lista com os nomes dos carros. Os anúncios são classificados por título, que normalmente é a ção do carro. Um problema que pode enfrentar ocorre quando alguns carros incluem o ano do carro antes da 3.º andar. O problema é que a funcionalidade de tipo incorporado da caixa de listas classifica apenas por códigos de caracteres; coloca todos os anúncios começando com datas em primeiro lugar, seguido pelos anúncios começando com a fazer.

Para corrigir isto, você pode criar um procedimento de tipo em uma classe que usa o tipo alfabético padrão na maioria das caixas de lista, mas é capaz de mudar no tempo de execução para o procedimento de classificação personalizado para anúncios de carros. Para isso, você passa o procedimento de classificação personalizada para a classe tipo no tempo de execução, usando delegados.

EndereçosOf e Expressões Lambda

Cada classe de delegado define um construtor que é aprovado a especificação de um método de objeto. Um argumento para um construtor delegado deve ser uma referência a um método, ou uma expressão lambda.

Para especificar uma referência a um método, utilize a seguinte sintaxe:

AddressOf [expression.]methodName

O tipo de tempo de compilação deve expression ser o nome de uma classe ou de uma interface que contenha um método do nome especificado cuja assinatura corresponda à assinatura da classe de delegado. Pode methodName ser um método partilhado ou um método de instância. O methodName não é opcional, mesmo que crie um delegado para o método padrão da classe.

Para especificar uma expressão lambda, utilize a seguinte sintaxe:

Function(Comoparmtype, parm2 Como type2, ...])expression

O exemplo a seguir mostra expressões AddressOf de lambda e lambda utilizadas para especificar a referência para um delegado.

Module Module1

    Sub Main()
        ' Create an instance of InOrderClass and assign values to the properties.
        ' InOrderClass method ShowInOrder displays the numbers in ascending 
        ' or descending order, depending on the comparison method you specify.
        Dim inOrder As New InOrderClass
        inOrder.Num1 = 5
        inOrder.Num2 = 4

        ' Use AddressOf to send a reference to the comparison function you want
        ' to use.
        inOrder.ShowInOrder(AddressOf GreaterThan)
        inOrder.ShowInOrder(AddressOf LessThan)

        ' Use lambda expressions to do the same thing.
        inOrder.ShowInOrder(Function(m, n) m > n)
        inOrder.ShowInOrder(Function(m, n) m < n)
    End Sub

    Function GreaterThan(ByVal num1 As Integer, ByVal num2 As Integer) As Boolean
        Return num1 > num2
    End Function

    Function LessThan(ByVal num1 As Integer, ByVal num2 As Integer) As Boolean
        Return num1 < num2
    End Function

    Class InOrderClass
        ' Define the delegate function for the comparisons.
        Delegate Function CompareNumbers(ByVal num1 As Integer, ByVal num2 As Integer) As Boolean
        ' Display properties in ascending or descending order.
        Sub ShowInOrder(ByVal compare As CompareNumbers)
            If compare(_num1, _num2) Then
                Console.WriteLine(_num1 & "  " & _num2)
            Else
                Console.WriteLine(_num2 & "  " & _num1)
            End If
        End Sub

        Private _num1 As Integer
        Property Num1() As Integer
            Get
                Return _num1
            End Get
            Set(ByVal value As Integer)
                _num1 = value
            End Set
        End Property

        Private _num2 As Integer
        Property Num2() As Integer
            Get
                Return _num2
            End Get
            Set(ByVal value As Integer)
                _num2 = value
            End Set
        End Property
    End Class
End Module

A assinatura da função deve corresponder à do tipo delegado. Para mais informações sobre expressões de lambda, consulte Lambda Expressions. Para mais exemplos de expressão lambda e AddressOf atribuições aos delegados, consulte Conversão de Delegado Relaxado.

Título Descrição
Como: Invocar um Método delegado Fornece um exemplo que mostra como associar um método a um delegado e, em seguida, invocar esse método através do delegado.
Como: Passar procedimentos para outro procedimento em Visual Basic Demonstra como usar os delegados para passar um procedimento para outro procedimento.
Conversão de delegado relaxado Descreve como pode atribuir submarinos e funções a delegados ou manipuladores mesmo quando as suas assinaturas não são idênticas
Eventos Fornece uma visão geral dos acontecimentos em Visual Basic.