Extender las funcionalidades de una clase a través de delegados

Extender las funcionalidades de una clase a través de delegados

Supongamos que hemos creado una clase, con el nombre ManipFecha, que tiene una propiedad a la que asignamos una fecha, y un método que devuelve la fecha formateada. Ver el Código fuente 330.

Module Module1 Sub Main() Dim loManipFecha As ManipFecha loManipFecha = New ManipFecha() loManipFecha.Fecha = #6/27/2002 7:40:00 PM# Console.WriteLine("Fecha larga: {0}", loManipFecha.DevFechaLarga())

Console.ReadLine() End Sub End Module

Public Class ManipFecha Private mdtFecha As Date

Public Sub New() mdtFecha = Date.Now End Sub

Public Property Fecha() As Date Get Return mdtFecha End Get

Set(ByVal Value As Date) mdtFecha = Value End Set End Property

Public Function DevFechaLarga() As String Return mdtFecha.ToLongDateString() End Function End Class

Código fuente 330

Después de finalizar el desarrollo de la clase y distribuirla, se presenta el siguiente problema: los programadores que la utilizan, disponen de rutinas de formateo propias que necesitarían implementar en nuestra clase.

Este punto, evidentemente, lo podríamos resolver utilizando herencia; no obstante, vamos a solucionar el problema mediante delegados. Por lo tanto, añadiremos un delegado a la clase ManipFecha, y un

Programación con Visual Basic .NET © Grupo EIDOS

método que lo invoque; al ejecutar este método, le pasaremos la dirección del procedimiento que contiene la rutina personalizada de formateo. Ver Código fuente 331.

Module Module1 Sub Main() ' crear un objeto de la clase Dim loManipFecha As ManipFecha loManipFecha = New ManipFecha() loManipFecha.Fecha = #6/27/2002 7:40:00 PM#

' llamar ahora al método que ejecuta un delegate; ' le pasamos a este método la dirección del ' procedimiento que el delegate debe invocar Dim lsFormatoResultado As String lsFormatoResultado = loManipFecha.FormateoExterno(AddressOf ObtenerHora) Console.WriteLine("Formateo externo resultante: {0}", lsFormatoResultado) Console.ReadLine()

End Sub

' este es un procedimiento que contiene una rutina ' personalizada de formateo, y que será invocado ' desde el delegate del objeto Public Function ObtenerHora(ByVal ldtFecha As Date) As String

Return ldtFecha.ToString("H:m") End Function End Module

Public Class ManipFecha ' .... ' .... ' declarar un delegado, a través del cual, ' ejecutaremos rutinas de código externas a la clase Public Delegate Function RealizaFormato(ByVal ldtFecha As Date) As String ' .... ' .... ' este método utiliza un delegado pasado como ' parámetro para invocar a un procedimiento externo ' a la clase Public Function FormateoExterno(ByVal loDelegFormat As RealizaFormato) As

String Return loDelegFormat.Invoke(mdtFecha) End Function End Class

Código fuente 331

No obstante, si disponemos de un conjunto más extenso de rutinas de formateo, lo mejor es aglutinarlas todas en métodos de una clase, invocando a estos métodos desde la clase que contiene el delegado.

El Código fuente 332 muestra la clase Formatos, en la que hemos creado dos métodos que realizan operaciones de formato.

Public Class Formatos ' los métodos de esta clase, reciben una fecha a la que ' aplican un formato y devuelven una cadena con el ' formato resultante Public Function Marinero(ByVal ldtFecha As Date) As String

Return ldtFecha.ToString("Cua\derno \de bi\tácora: " & _

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

"en el año yyyy, dd \de MMMM") End Function

Shared Function Espacial(ByVal ldtFecha As Date) As String Return ldtFecha.ToString("Diario e\s\telar: " & _ "MMM-d-yyyy / Sec\tor Ga\m\ma") End Function End Class

Código fuente 332

Para conseguir, ya en Main( ), que el delegado de la clase ManipFecha ejecute el código de la clase Formatos, podemos utilizar dos técnicas.

Por un lado, instanciamos un objeto de Formatos, y pasamos al método FormateoExterno( ), del objeto ManipFecha, la dirección del método Marinero( ) del objeto Formatos.

Por otra parte, en lo referente al método Espacial( ) de la clase Formatos, no es necesario crear un objeto. Debido a que dicho método es compartido, podemos pasar su dirección al método FormateoExterno( ), del objeto ManipFecha.

Module Module1 Sub Main() ' crear un objeto de la clase Dim loManipFecha As ManipFecha loManipFecha = New ManipFecha() loManipFecha.Fecha = #6/27/2002 7:40:00 PM#

Dim lsFormatoResultado As String

' instanciar un objeto de la clase en la que tenemos ' los métodos personalizados de formateo Dim oFormato As New Formatos()

' ahora pasamos al método FormateoExterno() del objeto ' ManipFecha, la dirección de un método del objeto ' Formatos, en donde tenemos una rutina personalizada ' de formateo de fecha lsFormatoResultado = loManipFecha.FormateoExterno(AddressOf

oFormato.Marinero)

Console.WriteLine("Formato estilo marinero: {0}", lsFormatoResultado)

' aquí efectuamos la misma operación que antes, ' pero pasamos como parámetro un método shared ' de la clase Formatos, es decir, no es necesario ' instanciar un objeto de Formatos lsFormatoResultado = loManipFecha.FormateoExterno(AddressOf

Formatos.Espacial)

Console.WriteLine("Formato estilo espacial: {0}", lsFormatoResultado)

Console.ReadLine() End Sub End Module

Código fuente 333

Programación con Visual Basic .NET © Grupo EIDOS