Eventi di classi base
-
22-08-2019 - |
Domanda
Ok, quindi ho una classe di base che dichiara il StatusTextChanged
evento. La mia classe del bambino, naturalmente non può sollevare direttamente questo evento.
Così finisco con qualcosa di simile (per semplicità):
Public MustInherit Class FooBase
Public Event StatusTextChanged(ByVal StatusText As String)
Protected Sub RaiseStatusTextChangedEvent(ByVal StatusText As String)
RaiseEvent StatusTextChanged(StatusText)
End Sub
End Class
E poi in classe figlia che io chiamo
MyBase.RaiseStatusTextChangedEvent("something")
.
C'è un modo migliore o più consigliati per fare questo?
modifica: VB.NET o C #, in entrambi i casi funziona essenzialmente la stessa
.modifica: Così, dopo le risposte, io sono a questo nella classe base, quindi basta impostare la proprietà StatusText nella classe figlia ...
Public Event StatusTextChanged(ByVal StatusText As String)
Private _StatusText As String = "Idle."
Public Property StatusText() As String
Get
Return _StatusText
End Get
Protected Set(ByVal value As String)
RaiseEvent StatusTextChanged(value)
End Set
End Property
Soluzione
Direi che si è piuttosto vicino al modo in cui recommeneded (o almeno quello che consiglio).
Vorrei fare alcune modifiche al codice, data una scelta:
- Fai StatusTextChanged
Protected Overridable
- Wrap StatusText in una classe EventArgs personalizzati
- Modificare la dichiarazione StatusTextChanged in
Public Event StatusTextChanged As EventHandler(Of YourCustomEventArgs)
Il codice risultante:
La classe EventArgs personalizzati:
Public Class TextEventArgs
Inherits EventArgs
Private _text As String
Public Sub New(ByVal text As String)
_text = text
End Sub
Public ReadOnly Property Text() As String
Get
Return _text
End Get
End Property
End Class
L'implementazione evento nella vostra classe di base:
Public Event StatusTextChanged As EventHandler(Of TextEventArgs)
Protected Overridable Sub OnStatusTextChanged(ByVal e As TextEventArgs)
RaiseEvent StatusTextChanged(Me, e)
End Sub
... e, infine, una linea di codice per la generazione dell'evento; sia nella classe di base o di una classe che eredita esso:
OnStatusTextChanged(New TextEventArgs("some text"))
Questa sarà più in linea con come gli eventi sono stati progettati nel resto del framework .NET.
Altri suggerimenti
A meno che non v'è la necessità specifica per la classe figlio di sovrascrivere un metodo della classe base, allora direi che chiamare l'implementazione della classe base è assolutamente la soluzione migliore.
Questo è più o meno il modo standard per la raccolta di eventi su una classe base tramite uno derivato per questo tipo di scenario.
Tuttavia, questo potrebbe cambiare un po 'a seconda di chi è il controllo della StatusText per la gerarchia. Se c'è un concreto StatusText campo supporto in FooBase che può essere modificato solo tramite funzioni di accesso, quindi non avrei lasciato il bambino a controllare l'innalzamento della manifestazione StatusTextChanged. Invece vorrei forzare l'innalzamento degli eventi all'interno del Setter della proprietà per StatusText. Questo dà la classe padre più controllo nel far rispettare tutti i contratti che vuole in giro quando e quando non sollevare detto evento.
Tuttavia, se lo StatusText è una proprietà che deve essere definito dalla classe derivata, sceglierei il percorso che si visualizzato.
Una possibilità si potrebbe avere è avvolgere la proprietà Status nella classe base, in modo che solleva l'evento stesso in un cambiamento (In C #, come non so VB e non hanno accesso a Visual Studio per il momento)
private string _status;
public string Status
{
get { return _status; }
protected set
{
if (_status == value) return;
_status = value;
StatusChanged(value);
}
}
Ecco il mio codice per un evento con un delegato e un parametro di testo di stato
Public Event Status As StatusEventHandler Protected Overridable Sub OnStatus(ByVal e As StatusEventArgs) RaiseEvent Status(Me, e) End Sub Public Delegate Sub StatusEventHandler(ByVal sender As Object, _ ByVal e As StatusEventArgs) <System.Serializable()> _ Public Class StatusEventArgs Inherits System.EventArgs Public Sub New() End Sub Public Sub New(ByVal statusText As String) _StatusText = statusText End Sub ' Enter code here for event properties, etc. Private _StatusText As String = "" Public Property StatusText() As String Get Return _StatusText End Get Set(ByVal value As String) _StatusText = value End Set End Property End Class