2008-10-01 11 views

Respuesta

9

Reemplazar en lugar de asociar un delegado dará lugar a un código más eficiente, por lo que generalmente se recomienda que siempre haces esto siempre que sea posible. Para obtener más información, consulte this MSDN article. Aquí hay una cita pertinente:

El método OnEventName protegida también permite que las clases derivadas para anular el evento sin asociar un delegado para ella. Una clase derivada siempre debe llamar al el método OnEventName de la clase base para asegurarse de que los delegados registrados reciban el evento.

+0

Estoy de acuerdo, anular ftw – mmcdole

+0

Curiosamente, las directrices de diseño establecen que cuando se crea un OnFoo virtual () método, el evento Foo correspondiente debe dispararse incluso si una clase descendente no llama a base.OnFoo()! Sin embargo, sería bastante incómodo hacerlo realidad. –

+0

@Matt: vacío privado RaiseFoo() { /* Llamar a OnFoo para las clases derivadas */ this.OnFoo(); /* Raise foo event (funciona incluso si base.OnFoo nunca es invocado por clases derivadas) */ ... } virtual protegido vacío OnFoo() {/ * no hace nada * /} –

6

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 devolución del evento (es decir, propiedades modificadas en el objeto EventArgs).

+0

+1 Esto es exactamente el razón. Puede garantizar * exactamente * cuando su código se ejecuta en relación con los controladores de eventos suscritos por el consumidor. – Noldorin

0

Si reemplaza al igual que Kent Boogaart comenta que tendrá que tener cuidado para volver a llamar base.OnClick para permitir suscripciones de eventos a ser llamados

0

hereditario clase nunca debe suscribirse a él sus propios eventos, o es la clase base ' eventos.

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. (see that source code here)

0

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.

3

Tenga en cuenta que (al menos en .NET 2.0) he encontrado algunos lugares en el marco (específicamente en la clase DataTable) donde el método OnFoo es solo llamado cuando se ha manejado el evento Foo correspondiente. Esto contraviene las pautas de diseño del marco pero estamos atrapados con eso.

que he recibido alrededor de ella por el manejo del evento con un manejador de maniquí 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 
    } 
} 
+0

Eso es interesante, no lo sabía. Es posible codificarlo así, lo cual es aterrador ... – MagicKat

Cuestiones relacionadas