Delegati come parametri in VB.NET
Domanda
Backstory: sto usando log4net per gestire tutte le registrazioni per un progetto I ' sto lavorando su. Un particolare metodo può essere chiamato in diverse circostanze: alcune che garantiscono che i messaggi di registro siano errori e altre che garantiscono che i messaggi di registro siano avvisi.
Quindi, come esempio, come potrei girare
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
In qualcosa di più sulla falsariga di:
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
In modo che potessi chiamarlo e passare log.ErrorFormat o log.WarnFormat come delegato?
Sto usando VB.NET con VS 2008 e .NET 3.5 SP1. Inoltre, sono abbastanza nuovo per i delegati in generale, quindi se questa domanda deve essere formulata in modo diverso per rimuovere eventuali ambiguità, fammi sapere.
EDIT: Inoltre, come potrei inizializzare il delegato su ErrorFormat o WarnFormat nel costruttore della classe? Sarebbe facile come myDelegate = log.ErrorFormat
? Immagino che ci sia qualcosa di più (scusate la mia ignoranza sull'argomento: i delegati sono davvero qualcosa di cui voglio saperne di più, ma finora hanno eluso la mia comprensione).
Soluzione
Dichiara la tua firma delegata:
Public Delegate Sub Format(ByVal value As String)
Definisci la tua funzione Test:
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
Da qualche parte nel tuo codice chiama la tua funzione Test:
CheckDifference(Foo, Bar, AddressOf log.WriteWarn)
O
CheckDifference(Foo, Bar, AddressOf log.WriteError)
Altri suggerimenti
Prima devi dichiarare un delegato a livello di classe / modulo (tutto questo codice è dalla memoria / non testato):
Private Delegate Sub LogErrorDelegate(txt as string, byval paramarray fields() as string)
Quindi .. ti consigliamo di dichiararlo come proprietà alla tua classe, ad esempio
Private _LogError
Public Property LogError as LogErrorDelegate
Get
Return _LogError
End Get
Set(value as LogErrorDelegate)
_LogError = value
End Set
End Property
Il modo per creare un'istanza del delegato è:
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)
Per favore, perdona la formattazione: P
Fondamentalmente, però, crea il delegato che desideri, con la firma corretta, e passane l'indirizzo al metodo.