Delegados como parámetros en VB.NET
Pregunta
Trasfondo:Estoy usando log4net para manejar todos los registros de un proyecto en el que estoy trabajando.Se puede invocar un método particular en varias circunstancias diferentes: algunas que garantizan que los mensajes de registro sean errores y otras que garantizan que los mensajes de registro sean advertencias.
Entonces, como ejemplo, ¿cómo podría convertir
Public Sub CheckDifference(ByVal A As Integer, ByVal B As Integer)
If (B - A) > 5 Then
log.ErrorFormat("Difference ({0}) is outside of acceptable range.", (B - A))
End If
End Sub
En algo más parecido a:
Public Sub CheckDifference(ByVal A As Integer, ByVal B As Integer, "Some delegate info here")
If (B - A) > 5 Then
**delegateinfo**.Invoke("Difference ({0}) is outside of acceptable range.", (B - A))
End If
End Sub
¿Para poder llamarlo y pasar log.ErrorFormat o log.WarnFormat como delegado?
Estoy usando VB.NET con VS 2008 y .NET 3.5 SP1.Además, soy bastante nuevo con los delegados en general, así que si esta pregunta debe redactarse de manera diferente para eliminar cualquier ambigüedad, hágamelo saber.
EDITAR:Además, ¿cómo podría inicializar el delegado en ErrorFormat o WarnFormat en el constructor de la clase?¿Sería tan fácil como myDelegate = log.ErrorFormat
?Me imagino que hay más que eso (perdón por mi ignorancia sobre el tema; los delegados son realmente algo sobre lo que quiero aprender más, pero hasta ahora han eludido mi comprensión).
Solución
Declare la firma de su delegado:
Public Delegate Sub Format(ByVal value As String)
Defina su función de prueba:
Public Sub CheckDifference(ByVal A As Integer, _
ByVal B As Integer, _
ByVal format As Format)
If (B - A) > 5 Then
format.Invoke(String.Format( _
"Difference ({0}) is outside of acceptable range.", (B - A)))
End If
End Sub
En algún lugar de su código llame a su función de Prueba:
CheckDifference(Foo, Bar, AddressOf log.WriteWarn)
O
CheckDifference(Foo, Bar, AddressOf log.WriteError)
Otros consejos
Primero querrás declarar un delegado en el nivel Clase/Módulo (todo este código es de la memoria/no probado):
Private Delegate Sub LogErrorDelegate(txt as string, byval paramarray fields() as string)
Entonces ..querrás declararlo como una propiedad de tu clase, p.
Private _LogError
Public Property LogError as LogErrorDelegate
Get
Return _LogError
End Get
Set(value as LogErrorDelegate)
_LogError = value
End Set
End Property
La forma de crear una instancia del delegado es:
Dim led as New LogErrorDelegate(AddressOf log.ErrorFormat)
Public Delegate errorCall(ByVal error As String, Params objs As Objects())
CheckDifference(10, 0, AddressOf log.ErrorFormat)
Por favor perdona el formato :P
Básicamente, cree el delegado que desee, con la firma correcta, y pase su dirección al método.