Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Delegados são objetos que se referem a métodos. Às vezes, eles são descritos como ponteiros de função seguros para tipos porque são semelhantes aos ponteiros de função usados em outras linguagens de programação. Mas, ao contrário dos ponteiros de função, os delegados do Visual Basic são um tipo de referência baseado na classe System.Delegate. Os delegados podem fazer referência a métodos compartilhados — 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 você precisa de um intermediário entre um procedimento de chamada e o procedimento que está sendo chamado. Por exemplo, você pode desejar que um objeto que gera eventos possa chamar manipuladores de eventos diferentes em circunstâncias diferentes. Infelizmente, o objeto que gera os eventos não pode saber com antecedência qual manipulador de eventos está manipulando um evento específico. Visual Basic permite que você associe dinamicamente manipuladores de eventos com eventos, criando um delegado para você quando você usa a AddHandler instrução. Em tempo de execução, o delegado encaminha chamadas para o manipulador de eventos apropriado.
Embora você possa criar seus próprios delegados, na maioria dos casos, o Visual Basic cria o delegado e cuida dos detalhes para você. Por exemplo, uma Event instrução define implicitamente uma classe delegada nomeada <EventName>EventHandler como uma classe aninhada da classe que contém a Event instrução e com a mesma assinatura do evento. A AddressOf instrução cria implicitamente uma instância de um delegado que se refere a um procedimento específico. As duas linhas de código a seguir são equivalentes. Na primeira linha, você vê a criação explícita de uma instância de EventHandler, com uma referência ao método Button1_Click enviado como argumento. A segunda linha é uma maneira 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
Você pode usar a maneira abreviada de criar delegados em qualquer lugar onde o compilador possa determinar o tipo do delegado pelo contexto.
Declarando eventos que usam um tipo de delegado existente
Em algumas situações, pode ser útil declarar um evento para usar um tipo de delegado existente como seu delegado base. A sintaxe a seguir demonstra como:
Delegate Sub DelegateType()
Event AnEvent As DelegateType
Isso é útil quando você deseja rotear vários eventos para o mesmo manipulador.
Delegar variáveis e parâmetros
Você pode usar delegados para outras tarefas não relacionadas a eventos, como encadeamento livre ou com procedimentos que precisam chamar diferentes versões de funcionalidades em tempo de execução.
Por exemplo, suponha que você tenha um aplicativo de anúncios classificados que inclua uma caixa de listagem com os nomes dos carros. Os anúncios são classificados por título, que normalmente é a marca do carro. Um problema que você pode enfrentar ocorre quando alguns carros incluem o ano do carro antes da marca. O problema é que a funcionalidade de ordenação interna da caixa de listagem classifica apenas por códigos de caracteres; assim, coloca primeiro todos os anúncios que começam com datas, seguidos pelos que começam com o fabricante.
Para corrigir isso, você pode criar um procedimento de classificação em uma classe que usa a classificação alfabética padrão na maioria das caixas de listagem, mas é capaz de alternar em tempo de execução para o procedimento de classificação personalizado para anúncios de carros. Para fazer isto, passa o procedimento de ordenação personalizado à classe de ordenação em tempo de execução, utilizando delegados.
Expressões AddressOf e Lambda
Cada classe delegada define um construtor ao qual é passada 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, use a seguinte sintaxe:
AddressOf [expression.]methodName
O tipo de tempo de compilação do expression deve ser o nome de uma classe ou uma interface que contém um método do nome especificado cuja assinatura corresponde à assinatura da classe delegada. O methodName pode ser um método compartilhado ou um método de instância. O methodName não é opcional, mesmo se você criar um delegado para o método padrão da classe.
Para especificar uma expressão lambda, use a seguinte sintaxe:
Function ([parm As type, parm2 As type2, ...]) expression
O exemplo a seguir mostra tanto AddressOf como expressões lambda usadas 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 obter mais informações sobre expressões lambda, consulte Expressões lambda. Para mais exemplos de expressões lambda e atribuições AddressOf a delegados, consulte Conversão Relaxada de Delegado.
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 no Visual Basic | Demonstra como usar delegados para passar um procedimento para outro. |
| Conversão flexível de delegados | Descreve como se pode atribuir subs e funções a delegados ou manipuladores, mesmo quando as suas assinaturas não são idênticas |
| Eventos | Fornece uma visão geral de eventos no Visual Basic. |