Eventos en clases base
-
22-08-2019 - |
Pregunta
Ok, así que tienen una clase base que declara la StatusTextChanged
evento. Mi clase hija, por supuesto, no puede subir directamente a este evento.
Así que termino con algo como esto (por razones de simplicidad):
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
Y a continuación, en la clase de niño que llamo
MyBase.RaiseStatusTextChangedEvent("something")
.
¿Hay una manera mejor o más recomendado para hacer esto?
editar: VB.NET o C #, ya sea forma en que funciona esencialmente el mismo
.editar: Así que después de las respuestas, estoy en esto en la clase base, a continuación, sólo establecer la propiedad StatusText en la clase hija ...
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
Solución
Yo diría que son bastante cerca de la forma recommeneded (o al menos la que yo recomendaría).
Me gustaría hacer algunas modificaciones a su código, les da a elegir:
- Haga StatusTextChanged
Protected Overridable
- Wrap StatusText en una clase EventArgs personalizados
- Cambie la declaración StatusTextChanged en
Public Event StatusTextChanged As EventHandler(Of YourCustomEventArgs)
El código resultante:
La clase EventArgs personalizados:
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
La implementación evento en su clase base:
Public Event StatusTextChanged As EventHandler(Of TextEventArgs)
Protected Overridable Sub OnStatusTextChanged(ByVal e As TextEventArgs)
RaiseEvent StatusTextChanged(Me, e)
End Sub
... y, finalmente, una línea de código para provocar el evento; ya sea en la clase base o una clase que hereda:
OnStatusTextChanged(New TextEventArgs("some text"))
Esto será más acorde con la forma en eventos están diseñados dentro del resto de la plataforma .NET.
Otros consejos
A menos que haya una necesidad específica de su clase hija a reemplazar un método de la clase base, entonces yo diría que llamar a la implementación de la clase base es sin duda la mejor solución.
Esto es más o menos la forma estándar para eventos de recaudación en una clase de base a través de una una derivada para este tipo de escenario.
Sin embargo, esto podría cambiar un poco dependiendo de quién tiene el control de la StatusText para la jerarquía. Si hay un campo concreto respaldo StatusText en FooBase que sólo se puede cambiar a través de descriptores de acceso, entonces yo no dejaría que el niño controle la elevación del evento StatusTextChanged. En lugar de eso obligaría a la elevación de los eventos dentro del organismo de la propiedad para StatusText. Esto le da a la clase padre más control en el cumplimiento de los contratos que quiere torno a cuándo y cuándo no levantar dicho evento.
Sin embargo, si el StatusText es una propiedad que debe ser definido por la clase derivada, elegiría la ruta se está visualizando.
Una de las opciones que podría tener es envolver la propiedad Status en la clase base, por lo que plantea el propio evento en un cambio (En C # como no saben VB y no tienen acceso a Visual Studio en el momento)
private string _status;
public string Status
{
get { return _status; }
protected set
{
if (_status == value) return;
_status = value;
StatusChanged(value);
}
}
Aquí está mi código para un evento con un delegado y un parámetro de texto de estado
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