c# - method - Cuándo debe anular OnEvent en lugar de suscribirse al evento al heredar
sealed c# (6)
Anular en lugar de adjuntar un delegado dará como resultado un código más eficiente, por lo que generalmente se recomienda que siempre haga esto siempre que sea posible. Para obtener más información, consulte este artículo de MSDN . Aquí hay una cita pertinente:
El método protegido OnEventName también permite que las clases derivadas anulen el evento sin asociarle un delegado. Una clase derivada siempre debe llamar al método OnEventName de la clase base para garantizar que los delegados registrados reciban el evento.
¿Cuándo debería uno hacer lo siguiente?
class Foo : Control
{
protected override void OnClick(EventArgs e)
{
// new code here
}
}
A diferencia de esto?
class Foo : Control
{
public Foo()
{
this.Click += new EventHandler(Clicked);
}
private void Clicked(object sender, EventArgs e)
{
// code
}
}
El evento es para suscriptores externos. Cuando obtenga algún control, siempre anule el método OnEvent en lugar de suscribirse al evento. De esta forma, puede estar seguro de cuándo se llama su código, porque el evento real se dispara cuando llama a base.OnEvent (), y puede llamar esto antes que su código, después de su código, en el medio de su código o no en todas. También puede reaccionar en los valores de retorno del evento (es decir, las propiedades modificadas en el objeto EventArgs).
La suscripción al evento está destinada a un control para supervisar eventos en un control diferente. Para controlar su propio evento, OnClick está bien. Sin embargo, tenga en cuenta que Control.OnClick maneja la activación de esos eventos suscritos, por lo tanto, asegúrese de llamarlo en su reemplazo.
Si anula los comentarios de Kent Boogaart, deberá tener cuidado de llamar a la base de datos. Haga clic para permitir que se llamen las suscripciones a eventos.
Tenga en cuenta que (al menos en .NET 2.0) he encontrado algunos lugares en el marco (específicamente en la clase DataTable) donde solo se llama al método OnFoo cuando se maneja el evento Foo correspondiente. Esto contraviene las pautas de diseño del marco pero estamos atrapados con eso.
Lo he manejado manejando el evento con un manejador simulado en algún lugar de la clase, por ejemplo:
public class MyDataTable : DataTable
{
public override void EndInit()
{
base.EndInit();
this.TableNewRow += delegate(object sender, DataTableNewRowEventArgs e) { };
}
protected override void OnTableNewRow(DataTableNewRowEventArgs e)
{
base.OnTableNewRow(e);
// your code here
}
}
Una clase heredada nunca debería suscribirse a sus propios eventos, ni a los eventos de la clase base.
Ahora, si una clase tiene una instancia de otra clase diferente, puede consumir los eventos de esa clase y determinar si debe generar su propio evento o no.
Por ejemplo, desarrollé recientemente una clase MRU List. En él, había una serie de controles ToolStripMenuItem, cuyo evento de clic consumí. Después de que ese evento de clic se consumió, elevé el evento de mi clase. ( vea ese código fuente aquí )