2011-01-20 9 views
5

nunca se ha encontrado antes. Aquí está la muestra:C#: ¿no es posible acceder a los eventos de la clase padre?

using System; 

namespace Testing 
{ 
    public class Test 
    { 
     public event Action ActionRequired; 
    } 

    public class ChildTest : Test 
    { 
     public void DoSomething() 
     { 
      if (this.ActionRequired != null) 
       this.ActionRequired(); 
     } 
    } 
} 

Esto no funcionará, el error es que solo puedo acceder al evento desde la clase base.

No es difícil navegar (agregar un método protegido a la clase base que comprueba una invocación del evento y llamar a ese método desde las clases secundarias), pero realmente me pregunto ¿cuál es la idea detrás de esta restricción?

Saludos,

Sebi

+0

posible duplicado de [¿Por qué eventos no se pueden utilizar en de la misma manera en las clases derivadas que en la clase base en C#?] (http://stackoverflow.com/questions/253757/why-events-cant-be-used-in-the-same-way-in-derived- classes-as-in-the-base-class) –

Respuesta

13

No se pueden invocar los eventos de fuera de la clase en la que se han definido. Sin embargo, no es necesario; simplemente siga el patrón idiomático de declarar también un método protegido para disparar dicho evento.

class Whatever 
{ 
    public event EventHandler Foo; 

    protected virtual void OnFoo(EventArgs e) 
    { 
     EventHandler del = Foo; 
     if(del != null) 
     { 
      del(this, e); 
     } 
    } 
} 

Ahora descendientes de la clase "lo que" pueden disparar el evento llamando OnFoo() y pasando los EventArgs apropiadas objeto.

EDIT: En cuanto a por qué este es el comportamiento, Jon Skeet explicó bien en otro hilo (lo que significa también que esta cuestión es un duplicado, por lo que la votación para cerrar):

Cuando se declara una evento similar a un campo público, el compilador crea un evento público y un campo privado. Dentro de la misma clase (o clases anidadas) puede obtener directamente en el campo, p. invocar a todos los controladores. De otras clases, solo verá el evento, que solo permite la suscripción y la baja.

+0

Nunca supe esto. Buena información. –

+0

gracias, eso es lo que he hecho ahora! –

+0

No hay problema, revisa este hilo para más información: http://stackoverflow.com/questions/253757/why-events-cant-be-used-in-the-same-way-in-derived-classes-as- in-the-base-class # 253803 –

3

La sintaxis que se utiliza para declarar el evento en su ejemplo es el azúcar realidad sintáctica para algo como esto:

private Action _actionRequired; 
public event Action ActionRequired 
{ 
    add { _actionRequired += value; } 
    remove { _actionRequired -= value } 
} 

(el código real es un poco más compleja, por supuesto)

El La parte importante aquí es que el campo _actionRequired es privado. Solo el evento en sí es público, pero solo es un par de métodos para agregar/eliminar (similar a una propiedad). Entonces, lo único que puede hacer con el evento es suscribirse o anular su suscripción. El campo que contiene el delegado real es privado, por lo que solo se puede acceder desde la clase que lo declara. Cuando usa ActionRequired en la clase que lo declara, se refiere al campo de delegado o al evento en sí, según el contexto.

Pero desde cualquier otra clase, solo el evento es accesible, no el campo. Es por eso que no puede invocar al delegado de otra clase, incluso una clase derivada.

+0

Gracias @Thomas que me ayudan a entender cómo sucede esto –

1

Según respuesta añadida por @ThomasLevesque https://stackoverflow.com/a/4742280/3926461

puede declarar su acción sin necesidad de utilizar este azúcar sintáctica Al igual que el anterior a continuación:

public class Test 
{ 
    protected Action _actionRequired; 
    public event Action ActionRequired { 
     add { 
      _actionRequired += value; 
     } 
     remove { 
      _actionRequired += value; 
     } 
    } 
} 

public class ChildTest : Test 
{ 
    public void DoSomething() 
    { 
     if (this._actionRequired != null) 
      this._actionRequired(); 
    } 
} 
Cuestiones relacionadas