Delegados (Visual Basic)Delegates (Visual Basic)

Os delegados são objetos que se referem aos métodos.Delegates are objects that refer to methods. Às vezes, eles são descritos como ponteiros de função fortemente tipados porque eles são semelhante aos ponteiros de função usados em outras linguagens de programação.They are sometimes described as type-safe function pointers because they are similar to function pointers used in other programming languages. Mas, diferentemente dos ponteiros de função, os delegados de Visual Basic são um tipo de referência com base na System.Delegatede classe.But unlike function pointers, Visual Basic delegates are a reference type based on the class System.Delegate. Os delegados podem fazer referência a ambos os métodos compartilhados: os métodos que podem ser chamados sem uma instância específica de uma classe e os métodos de instância.Delegates can reference both shared methods — methods that can be called without a specific instance of a class — and instance methods.

Representantes e eventosDelegates and Events

Os delegados são úteis em situações em que é necessário um intermediário entre um procedimento de chamada e o procedimento sendo chamado.Delegates are useful in situations where you need an intermediary between a calling procedure and the procedure being called. Por exemplo, você pode desejar que um objeto que aciona eventos possa chamar manipuladores de eventos diferentes em diferentes circunstâncias.For example, you might want an object that raises events to be able to call different event handlers under different circumstances. Infelizmente, o objeto que aciona os eventos não pode saber de antemão quais manipulador de eventos estarão tratando um evento específico.Unfortunately, the object raising the events cannot know ahead of time which event handler is handling a specific event. Visual Basic permite associar dinamicamente manipuladores de eventos a eventos criando um delegado para você quando você usa a instrução AddHandler.Visual Basic lets you dynamically associate event handlers with events by creating a delegate for you when you use the AddHandler statement. No tempo de execução, o delegado encaminha chamadas para o manipulador de eventos apropriado.At run time, the delegate forwards calls to the appropriate event handler.

Embora você possa criar seus próprios delegados, na maioria dos casos Visual Basic cria o delegado e cuida dos detalhes para você.Although you can create your own delegates, in most cases Visual Basic creates the delegate and takes care of the details for you. Por exemplo, uma instrução Event define implicitamente uma classe delegada chamada <EventName>EventHandler como uma classe aninhada da classe que contém a instrução Event e com a mesma assinatura que o evento.For example, an Event statement implicitly defines a delegate class named <EventName>EventHandler as a nested class of the class containing the Event statement, and with the same signature as the event. A instrução AddressOf cria implicitamente uma instância de um delegado que se refere a um procedimento específico.The AddressOf statement implicitly creates an instance of a delegate that refers to a specific procedure. As duas linhas de código a seguir são equivalentes.The following two lines of code are equivalent. Na primeira linha, você vê a criação explícita de uma instância do EventHandler, com uma referência ao método Button1_Click enviado como o argumento.In the first line, you see the explicit creation of an instance of EventHandler, with a reference to method Button1_Click sent as the argument. A segunda linha é uma maneira mais conveniente de fazer a mesma coisa.The second line is a more convenient way to do the same thing.

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 forma mais simples de criar delegados em qualquer local que o compilador possa determinar o tipo do delegado pelo contexto.You can use the shorthand way of creating delegates anywhere the compiler can determine the delegate's type by the context.

Declarando eventos que usam um tipo delegado existenteDeclaring Events that Use an Existing Delegate Type

Em algumas situações, convém declarar um evento para usar um tipo delegado existente como seu delegado subjacente.In some situations, you may want to declare an event to use an existing delegate type as its underlying delegate. A sintaxe a seguir demonstra como:The following syntax demonstrates how:

Delegate Sub DelegateType()
Event AnEvent As DelegateType

Isso é útil quando você deseja rotear vários eventos para o mesmo manipulador.This is useful when you want to route multiple events to the same handler.

Variáveis e parâmetros de delegadoDelegate Variables and Parameters

Você pode usar delegados para outras tarefas não relacionadas a eventos, como threading livre ou com os procedimentos que precisem chamar diferentes versões de funções no tempo de execução.You can use delegates for other, non-event related tasks, such as free threading or with procedures that need to call different versions of functions at run time.

Por exemplo, suponha que você tenha um aplicativo com anúncio classificado que inclui uma caixa de listagem com os nomes de carros.For example, suppose you have a classified-ad application that includes a list box with the names of cars. Os anúncios são classificados por título, que é, normalmente, a marca do carro.The ads are sorted by title, which is normally the make of the car. Um problema que você pode enfrentar ocorre quando alguns carros incluem o ano antes do fabricante.A problem you may face occurs when some cars include the year of the car before the make. O problema é que a funcionalidade interna de classificação da caixa de listagem classifica somente por códigos de caracteres. Ela coloca todos os anúncios começando com datas primeiro, seguidos de anúncios começando com o fabricante.The problem is that the built-in sort functionality of the list box sorts only by character codes; it places all the ads starting with dates first, followed by the ads starting with the make.

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 é possível mudar no tempo de execução para o procedimento de classificação personalizada para anúncios de carro.To fix this, you can create a sort procedure in a class that uses the standard alphabetic sort on most list boxes, but is able to switch at run time to the custom sort procedure for car ads. Para fazer isso, você passa o procedimento de classificação personalizada para a classe de classificação no tempo de execução usando delegados.To do this, you pass the custom sort procedure to the sort class at run time, using delegates.

Expressões lambda e AddressOfAddressOf and Lambda Expressions

Cada classe de delegado define um construtor que é passado para a especificação de um método do objeto.Each delegate class defines a constructor that is passed the specification of an object method. Um argumento para o construtor delegado deve ser uma referência a um método ou uma expressão lambda.An argument to a delegate constructor must be a reference to a method, or a lambda expression.

Para especificar uma referência a um método, use a seguinte sintaxe:To specify a reference to a method, use the following syntax:

AddressOf [expression.]methodNameAddressOf [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 coincide com a assinatura da classe delegada.The compile-time type of the expression must be the name of a class or an interface that contains a method of the specified name whose signature matches the signature of the delegate class. O methodName pode ser um método compartilhado ou um método de instância.The methodName can be either a shared method or an instance method. O methodName não é opcional, mesmo se você criar um delegado para o método padrão da classe.The methodName is not optional, even if you create a delegate for the default method of the class.

Para especificar uma expressão lambda, use a seguinte sintaxe:To specify a lambda expression, use the following syntax:

Function ([parm As type, parm2 As type2, ...]) expressionFunction ([parm As type, parm2 As type2, ...]) expression

O exemplo a seguir mostra as expressões lambda e AddressOf usadas para especificar a referência para um delegado.The following example shows both AddressOf and lambda expressions used to specify the reference for a delegate.

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 a do tipo delegado.The signature of the function must match that of the delegate type. Para obter mais informações sobre expressões lambda, consulte Expressões lambda.For more information about lambda expressions, see Lambda Expressions. Para obter mais exemplos de expressão lambda e atribuições AddressOf aos delegados, consulte Conversão de delegado amena.For more examples of lambda expression and AddressOf assignments to delegates, see Relaxed Delegate Conversion.

TitleTitle DescriçãoDescription
Como invocar um método delegadoHow to: Invoke a Delegate Method Fornece um exemplo que mostra como associar um método a um delegado e depois invoca esse método por meio do delegado.Provides an example that shows how to associate a method with a delegate and then invoke that method through the delegate.
Como passar procedimentos para outro procedimento no Visual BasicHow to: Pass Procedures to Another Procedure in Visual Basic Demonstra como usar delegados para passar um procedimento para outro.Demonstrates how to use delegates to pass one procedure to another procedure.
Conversão de Delegado ReduzidaRelaxed Delegate Conversion Descreve como você pode atribuir assinaturas e funções a delegados ou manipuladores mesmo quando as assinaturas não são idênticasDescribes how you can assign subs and functions to delegates or handlers even when their signatures are not identical
EventosEvents Fornece uma visão geral dos eventos no Visual Basic.Provides an overview of events in Visual Basic.