Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Los delegados son objetos que hacen referencia a métodos. A veces se describen como punteros de función seguros para tipos porque son similares a los punteros de función usados en otros lenguajes de programación. 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. Los delegados pueden hacer referencia a ambos métodos compartidos (métodos a los que se puede llamar sin una instancia específica de una clase) y métodos de instancia.
Delegados y eventos
Los delegados son útiles en situaciones en las que se necesita un intermediario entre un procedimiento de llamada y el procedimiento al que se llama. Por ejemplo, es posible que desee que un objeto que genere eventos pueda llamar a diferentes controladores de eventos en circunstancias diferentes. Desafortunadamente, el objeto que genera los eventos no puede saber con antelación qué controlador de eventos controla un evento específico. Visual Basic te permite asociar dinámicamente controladores de eventos a eventos mediante la creación automática de un delegado al utilizar la instrucción AddHandler
. En tiempo de ejecución, el delegado reenvía las llamadas al controlador de eventos adecuado.
Aunque puede crear sus propios delegados, en la mayoría de los casos, Visual Basic crea el delegado y se encarga de los detalles. Por ejemplo, una Event
instrucción define implícitamente una clase delegada denominada <EventName>EventHandler
como una clase anidada de la clase que contiene la Event
instrucción y con la misma firma que el evento. La instrucción AddressOf
crea implícitamente una instancia de un delegado que hace referencia a un procedimiento específico. Las dos líneas de código siguientes son equivalentes. En la primera línea, verá la creación explícita de una instancia de EventHandler
, con una referencia al método Button1_Click
enviado como argumento . La segunda línea es una manera más cómoda de hacer lo mismo.
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 usar la forma abreviada de crear delegados en cualquier lugar donde el compilador pueda determinar el tipo del delegado por el contexto.
Declaración de eventos que usan un tipo de delegado existente
En algunas situaciones, es posible que desee declarar un evento para usar un tipo de delegado existente como delegado subyacente. La siguiente sintaxis muestra cómo:
Delegate Sub DelegateType()
Event AnEvent As DelegateType
Esto resulta útil cuando desea enrutar varios eventos al mismo controlador.
Delegar variables y parámetros
Puede usar delegados para otras tareas no relacionadas con eventos, como subprocesamiento independiente o con procedimientos que necesiten llamar a diferentes versiones de funciones en tiempo de ejecución.
Por ejemplo, supongamos que tiene una aplicación de anuncios clasificados que incluye un cuadro de lista con los nombres de los coches. Los anuncios se ordenan por título, que normalmente es la marca del coche. Un problema que puede surgir ocurre cuando algunos coches incluyen el año del coche antes de la marca. El problema es que la funcionalidad de ordenación integrada del cuadro de lista solo ordena por códigos de caracteres; coloca todos los anuncios a partir de fechas en primer lugar, seguidos de los anuncios que comienzan por la marca.
Para corregir esto, puede crear un procedimiento de ordenación en una clase que use 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 anuncios de automóviles. 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.
Expresiones AddressOf y Lambda
Cada clase de delegado define un constructor al que se le pasa la especificación de un método de objeto. Un argumento para un constructor delegado debe ser una referencia a un método o a una expresión lambda.
Para especificar una referencia a un método, use la sintaxis siguiente:
AddressOf
[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.
methodName
puede ser un método compartido o un método de instancia. El methodName
no es opcional, incluso si crea un delegado para el método predeterminado de la clase.
Para especificar una expresión lambda, use la sintaxis siguiente:
Function
([parm
As type
, parm2
As type2
, ...]) expression
En el siguiente ejemplo se muestran tanto AddressOf
como expresiones lambda utilizadas para especificar la referencia para un 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
La firma de la función debe coincidir con la del tipo de delegado. Para obtener más información sobre las expresiones lambda, vea Expresiones lambda. Para obtener más ejemplos de expresión lambda y asignaciones de AddressOf
a delegados, vea Conversión de delegado flexible.
Temas relacionados
Título | Descripción |
---|---|
Procedimiento para invocar un método delegate | Proporciona un ejemplo que muestra cómo asociar un método a un delegado y, a continuación, invocar ese método a través del delegado. |
Cómo: Pasar procedimientos a otro procedimiento en Visual Basic | Muestra cómo usar delegados para pasar un procedimiento a otro procedimiento. |
Conversión de delegado flexible | Describe cómo puede asignar subrutinas y funciones a delegados o controladores, incluso cuando sus firmas no son idénticas. |
Eventos | Proporciona información general sobre los eventos en Visual Basic. |