Delegados (Visual Basic)Delegates (Visual Basic)

Los delegados son objetos que hacen referencia a métodos.Delegates are objects that refer to methods. A veces se describen como punteros de función con seguridad de tipos porque son similares a los punteros de función utilizados en otros lenguajes de programación.They are sometimes described as type-safe function pointers because they are similar to function pointers used in other programming languages. Pero a diferencia de los punteros de función, los delegados de Visual Basic son un tipo de referencia basado en la clase System.Delegate.But unlike function pointers, Visual Basic delegates are a reference type based on the class System.Delegate. Los delegados pueden hacer referencia a los métodos compartidos, métodos a los que se puede llamar sin una instancia específica de una clase, y a los métodos de instancia.Delegates can reference both shared methods — methods that can be called without a specific instance of a class — and instance methods.

Delegados y eventosDelegates and Events

Los delegados son útiles en situaciones donde es necesario un intermediario entre un procedimiento que realiza la llamada y el procedimiento que la recibe.Delegates are useful in situations where you need an intermediary between a calling procedure and the procedure being called. Por ejemplo, puede que necesite un objeto que provoca que los eventos puedan llamar a controladores de eventos diferentes en distintas circunstancias.For example, you might want an object that raises events to be able to call different event handlers under different circumstances. Lamentablemente, el objeto que provoca los eventos no puede conocer de antemano qué controlador de eventos controla un 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 controladores de eventos dinámicamente asociar con eventos mediante la creación de un delegado para cuando se usa el AddHandler instrucción.Visual Basic lets you dynamically associate event handlers with events by creating a delegate for you when you use the AddHandler statement. En tiempo de ejecución, el delegado reenvía las llamadas al controlador de eventos adecuado.At run time, the delegate forwards calls to the appropriate event handler.

Aunque puede crear a sus propios delegados, en muchos casos, Visual Basic crea al delegado y se encarga de los detalles por usted.Although you can create your own delegates, in most cases Visual Basic creates the delegate and takes care of the details for you. Por ejemplo, una instrucción Event define implícitamente una clase delegada denominada <EventName>EventHandler como una clase anidada de la clase que contiene la instrucción Event, y con la misma firma que el 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. La instrucción AddressOf crea implícitamente una instancia de un delegado que hace referencia a un procedimiento específico.The AddressOf statement implicitly creates an instance of a delegate that refers to a specific procedure. Las dos líneas de código siguientes son equivalentes.The following two lines of code are equivalent. En la primera línea, verá que la creación explícita de una instancia de EventHandler, con una referencia al método Button1_Click enviada como 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. La segunda línea es una manera más práctica de conseguir el mismo resultado.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

Puede utilizar la forma abreviada para crear delegados en cualquier lugar en que el compilador puede determinar el tipo de delegado en función del contexto.You can use the shorthand way of creating delegates anywhere the compiler can determine the delegate's type by the context.

Declaración de eventos que usan un tipo de delegado existenteDeclaring Events that Use an Existing Delegate Type

En algunas situaciones, puede declarar un evento para utilizar un tipo de delegado existente como su delegado subyacente.In some situations, you may want to declare an event to use an existing delegate type as its underlying delegate. La sintaxis siguiente muestra cómo:The following syntax demonstrates how:

Delegate Sub DelegateType()
Event AnEvent As DelegateType

Esto es útil cuando desea enrutar diversos eventos hacia el mismo controlador.This is useful when you want to route multiple events to the same handler.

Variables y parámetros delegadosDelegate Variables and Parameters

Puede utilizar delegados para otras tareas relacionadas sin eventos, como un subproceso libre, o con procedimientos que necesiten llamar a diferentes versiones de funciones en tiempo de ejecución.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 ejemplo, suponga que tiene una aplicación de anuncios clasificados que incluye un cuadro de lista con los nombres de los automóviles.For example, suppose you have a classified-ad application that includes a list box with the names of cars. Los anuncios se ordenan por título, que suele ser la marca del automóvil.The ads are sorted by title, which is normally the make of the car. Se puede plantear un problema si algunos coches incluyen el año del automóvil antes de la marca.A problem you may face occurs when some cars include the year of the car before the make. El problema es que la funcionalidad de ordenación integrada del cuadro de lista ordena únicamente por códigos de caracteres; coloca todos los anuncios que empiezan con las fechas primero, seguidos de los anuncios que empiezan con la marca.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 solucionar este problema, puede crear un procedimiento de ordenación en una clase que usa la ordenación alfabética estándar en la mayoría de los cuadros de lista, pero puede cambiar en tiempo de ejecución al procedimiento de ordenación personalizado para los anuncios de los automóviles.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 ello, pasa el procedimiento de ordenación personalizado a la clase de ordenación en tiempo de ejecución, mediante el uso de delegados.To do this, you pass the custom sort procedure to the sort class at run time, using delegates.

Expresiones lambda y AddressOfAddressOf and Lambda Expressions

Cada clase delegada define un constructor que se pasa la especificación de un método de objeto.Each delegate class defines a constructor that is passed the specification of an object method. Un argumento para un constructor delegado debe ser una referencia a un método o una expresión lambda.An argument to a delegate constructor must be a reference to a method, or a lambda expression.

Para especificar una referencia a un método, utilice la siguiente sintaxis:To specify a reference to a method, use the following syntax:

AddressOf [expression.]methodNameAddressOf [expression.]methodName

El tipo de tiempo de compilación de expression debe ser el nombre de una clase o una interfaz que contiene un método del nombre especificado cuya firma coincida con la firma de la clase 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. methodName puede ser un método compartido o un método de instancia.The methodName can be either a shared method or an instance method. methodName no es opcional, incluso si se crea un delegado para el método predeterminado de la clase.The methodName is not optional, even if you create a delegate for the default method of the class.

Para especificar una expresión lambda, utilice la siguiente sintaxis:To specify a lambda expression, use the following syntax:

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

En el ejemplo siguiente se muestran las expresiones lambda y AddressOf usadas para especificar la referencia de un 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

La firma de la función debe coincidir con la del tipo de delegado.The signature of the function must match that of the delegate type. Para obtener más información sobre las expresiones lambda, vea Expresiones lambda.For more information about lambda expressions, see Lambda Expressions. Para obtener más ejemplos de expresión lambda y asignaciones de AddressOf a delegados, vea Conversión de delegado flexible.For more examples of lambda expression and AddressOf assignments to delegates, see Relaxed Delegate Conversion.

TítuloTitle DescripciónDescription
Cómo: Invocar un método delegadoHow to: Invoke a Delegate Method Proporciona un ejemplo que muestra cómo asociar un método a un delegado y después invocar ese método a través del delegado.Provides an example that shows how to associate a method with a delegate and then invoke that method through the delegate.
Cómo: Pasar procedimientos a otro procedimiento en Visual BasicHow to: Pass Procedures to Another Procedure in Visual Basic Muestra cómo utilizar los delegados para pasar un procedimiento a otro procedimiento.Demonstrates how to use delegates to pass one procedure to another procedure.
Conversión de delegado flexibleRelaxed Delegate Conversion Describe cómo asignar subfunciones y funciones a delegados o controladores incluso cuando sus firmas no son idénticas.Describes how you can assign subs and functions to delegates or handlers even when their signatures are not identical
EventosEvents Proporciona información general sobre eventos en Visual Basic.Provides an overview of events in Visual Basic.