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
(Comoparm
type
, 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ópicos relacionados
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. |