Creación de delegados

Creación de delegados

Seguidamente, y ya en un procedimiento, declaramos una variable correspondiente al tipo del delegado. A continuación, conectamos el delegado con el procedimiento que posteriormente deberá ejecutar, empleando la palabra clave AddressOf, seguida del nombre del procedimiento.

AddressOf devuelve el puntero o dirección de entrada al procedimiento, que será lo que utilice el delegado para saber la ubicación del procedimiento que debe ejecutar. Por último, para ejecutar el procedimiento al que apunta el delegado, llamaremos a su método Invoke( ). En el Código fuente 325, se muestran dos técnicas para crear un delegado; la segunda es mucho más simple, pero en ambas, el resultado es el mismo: la ejecución indirecta del procedimiento MostrarTexto( ), a través del delegado.

Module Module1 Public Delegate Sub VerMensaje()

' Modo 1 ----------------------------- Sub Main()

' declarar un delegado Dim loDelegTexto As VerMensaje

' obtener la dirección del procedimiento a ejecutar ' y asignarla al delegado loDelegTexto = AddressOf MostrarTexto

' ejecutar el procedimiento a través del delegado loDelegTexto.Invoke() End Sub

' Modo 2 ----------------------------- Sub Main()

' declarar el delegado y asociar con una dirección ' o puntero a un procedimiento Dim loDelegTexto As New VerMensaje(AddressOf MostrarTexto)

loDelegTexto.Invoke() End Sub

' *********************************************** ' este será el procedimiento invocado (ejecutado) ' por el delegado Public Sub MostrarTexto()

Console.WriteLine("Hola, esto es una prueba con delegados") End Sub End Module

Código fuente 325

© Grupo EIDOS 22. Delegación de código y eventos

Una de las ventajas de este tipo de entidades de la plataforma, consiste en que un mismo delegado puede llamar a métodos diferentes de objetos distintos. En el caso del Código fuente 326, un delegado invoca a dos procedimientos diferentes.

Module Module1 Public Delegate Sub VerMensaje()

Sub Main() Dim loDelegMensa As VerMensaje

loDelegMensa = AddressOf MostrarTexto loDelegMensa.Invoke()

loDelegMensa = AddressOf VisualizarFecha loDelegMensa.Invoke()

End Sub

' procedimientos ejecutados por los delegados Public Sub MostrarTexto() Console.WriteLine("Hola, esto es una prueba con delegados") End Sub

Public Sub VisualizarFecha() Dim ldtFecha As Date ldtFecha = Date.Today Console.WriteLine("La fecha actual es {0:G}", ldtFecha)

End Sub End Module

Código fuente 326

Si delegamos un procedimiento que admite parámetros, a la hora de invocarlo con el delegado, debemos pasar al método Invoke( ) los valores de los parámetros, en el mismo orden que especifica el procedimiento. Veamos el ejemplo del Código fuente 327.

Module Module1 Public Delegate Sub Aviso(ByVal lsTexto As String)

Sub Main() Dim loGestionarAviso As Aviso

loGestionarAviso = New Aviso(AddressOf Normal) loGestionarAviso.Invoke("Recuerda apagar el servidor")

loGestionarAviso = New Aviso(AddressOf Urgente) loGestionarAviso.Invoke("Realizar la copia de seguridad")

Console.ReadLine() End Sub

Public Sub Normal(ByVal lsTexto As String) Console.WriteLine("* {0} *", lsTexto) End Sub Public Sub Urgente(ByVal lsTexto As String)

Console.WriteLine("¡¡¡ {0} !!!", lsTexto.ToUpper) End Sub End Module

Código fuente 327

Programación con Visual Basic .NET © Grupo EIDOS

En el caso de delegación hacia funciones, cuando invoquemos el código con el delegado, deberemos obtener el valor de retorno de la función. Veamos el ejemplo del Código fuente 328.

Module Module1 Public Delegate Function Obtener(ByVal ldtFecha As Date) As String

Sub Main() ' obtener una fecha Dim ldtFecha As Date Console.WriteLine("Introducir una fecha") ldtFecha = Console.ReadLine()

' crear un delegado, y según el mes de la fecha obtenida, ' el delegado ejecutará una función determinada Dim loManipFecha As Obtener Dim lsResultado As String If ldtFecha.Month < 6 Then

loManipFecha = AddressOf RecuperaMes Else loManipFecha = AddressOf DameDiaSemana End If

' como el delegado ejecuta funciones, recuperamos el valor ' de retorno al invocar la función correspondiente lsResultado = loManipFecha.Invoke(ldtFecha) Console.WriteLine("El resultado obtenido es: {0}", lsResultado)

Console.ReadLine() End Sub

Public Function RecuperaMes(ByVal ldtFecha As Date) As String Return ldtFecha.ToString("MMMM") End Function

Public Function DameDiaSemana(ByVal ldtFecha As Date) As String Return ldtFecha.ToString("dddd") End Function End Module

Código fuente 328

Aunque en los anteriores ejemplos, hemos invocado los delegados desde el mismo procedimiento en que han sido creados, podemos, naturalmente, pasar un delegado como parámetro a un procedimiento, y que sea dicho procedimiento el encargado de ejecutar el código que guarda el delegado. De esta forma, si el anterior ejemplo lo variamos ligeramente, y añadimos un procedimiento que reciba el delegado y el parámetro, obtendríamos el Código fuente 329.

Sub Main() ' ...... ' ...... ' llamar a un procedimiento que ejecuta el delegado Gestionar(loManipFecha, ldtFecha) ' ...... ' ......

End Sub

' en este procedimiento uno de los parámetros es un delegado ' y el otro el valor que utilizará el delegado como parámetro Public Sub Gestionar(ByVal loDelObtener As Obtener, _

© Grupo EIDOS 22. Delegación de código y eventos

ByVal ldtUnaFecha As Date)

Dim lsResultado As String lsResultado = loDelObtener.Invoke(ldtUnaFecha) Console.WriteLine("El resultado obtenido es: {0}", lsResultado)

End Sub

Código fuente 329