son - C#: levantando un evento heredado
qué es un evento c# (4)
¿Asumo que no puedo acceder a estos eventos al igual que a otros miembros heredados?
Precisamente. Es costumbre proporcionar una función protegida OnXyz
o RaiseXyz
para cada evento en la clase base para habilitar el aumento desde las clases heredadas. Por ejemplo:
public event EventHandler Loading;
protected virtual void OnLoading() {
EventHandler handler = Loading;
if (handler != null)
handler(this, EventArgs.Empty);
}
Llamado en la clase heredada:
OnLoading();
Tengo una clase base que contiene los siguientes eventos:
public event EventHandler Loading;
public event EventHandler Finished;
En una clase que hereda de esta clase base, trato de plantear el evento:
this.Loading(this, new EventHandler()); // All we care about is which object is loading.
Recibo el siguiente error:
El evento ''BaseClass.Loading'' solo puede aparecer en el lado izquierdo de + = o - = (BaseClass '')
¿Asumo que no puedo acceder a estos eventos al igual que a otros miembros heredados?
Lo que tienes que hacer es esto:
En su clase base (donde ha declarado los eventos), cree métodos protegidos que se puedan usar para generar los eventos:
public class MyClass
{
public event EventHandler Loading;
public event EventHandler Finished;
protected virtual void OnLoading(EventArgs e)
{
EventHandler handler = Loading;
if( handler != null )
{
handler(this, e);
}
}
protected virtual void OnFinished(EventArgs e)
{
EventHandler handler = Finished;
if( handler != null )
{
handler(this, e);
}
}
}
(Tenga en cuenta que probablemente deba cambiar esos métodos, para comprobar si debe invocar el manejador de eventos o no).
Luego, en las clases que heredan de esta clase base, puede llamar a los métodos OnFinished o OnLoading para plantear los eventos:
public AnotherClass : MyClass
{
public void DoSomeStuff()
{
...
OnLoading(EventArgs.Empty);
...
OnFinished(EventArgs.Empty);
}
}
Puedes intentarlo de esta manera. Funciona para mí:
public delegate void MyEventHaldler(object sender, EventArgs e);
public class B
{
public virtual event MyEventHaldler MyEvent;
protected override void OnChanged(EventArgs e)
{
if (MyEvent != null)
MyEvent(this, e);
}
}
public class D : B
{
public override event MyEventHaldler MyEvent;
protected override void OnChanged(EventArgs e)
{
if (MyEvent != null)
MyEvent(this, e);
}
}
Solo puede acceder a un evento en la clase de declaración, ya que .NET crea variables de instancia privadas detrás de las escenas que realmente contienen el delegado. Haciendo esto..
public event EventHandler MyPropertyChanged;
en realidad está haciendo esto;
private EventHandler myPropertyChangedDelegate;
public event EventHandler MyPropertyChanged
{
add { myPropertyChangedDelegate += value; }
remove { myPropertyChangedDelegate -= value; }
}
y haciendo esto ...
MyPropertyChanged(this, EventArgs.Empty);
es en realidad esto ...
myPropertyChangedDelegate(this, EventArgs.Empty);
Entonces, puede (obviamente) acceder solo a la variable de instancia de delegado privada desde dentro de la clase declarante.
La convención es proporcionar algo como esto en la clase declarante.
protected virtual void OnMyPropertyChanged(EventArgs e)
{
EventHandler invoker = MyPropertyChanged;
if(invoker != null) invoker(this, e);
}
A continuación, puede llamar a OnMyPropertyChanged(EventArgs.Empty)
desde cualquier lugar de esa clase o debajo de la jerarquía de herencia para invocar el evento.