С#: создание унаследованного события
У меня есть базовый класс, который содержит следующие события:
public event EventHandler Loading;
public event EventHandler Finished;
В классе, который наследуется от этого базового класса, я пытаюсь поднять событие:
this.Loading(this, new EventHandler()); // All we care about is which object is loading.
Я получаю следующую ошибку:
Событие "BaseClass.Loading" может появляться только с левой стороны + = или - = (BaseClass ')
Я предполагаю, что я не могу получить доступ к этим событиям так же, как другие унаследованные элементы?
Ответы
Ответ 1
Что вам нужно сделать, это:
В базовом классе (где вы объявили события) создайте защищенные методы, которые можно использовать для повышения событий:
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);
}
}
}
(Обратите внимание, что вам, вероятно, следует изменить эти методы, чтобы проверить, нужно ли вам вызывать обработчик событий или нет).
Затем в классах, которые наследуются от этого базового класса, вы можете просто вызвать методы OnFinished или OnLoading для повышения событий:
public AnotherClass : MyClass
{
public void DoSomeStuff()
{
...
OnLoading(EventArgs.Empty);
...
OnFinished(EventArgs.Empty);
}
}
Ответ 2
Вы можете получить доступ только к событию в объявляющем классе, так как .NET создает частные переменные экземпляра за кулисами, которые фактически удерживают делегата. Выполнение этого.
public event EventHandler MyPropertyChanged;
на самом деле делает это:
private EventHandler myPropertyChangedDelegate;
public event EventHandler MyPropertyChanged
{
add { myPropertyChangedDelegate += value; }
remove { myPropertyChangedDelegate -= value; }
}
и делать это...
MyPropertyChanged(this, EventArgs.Empty);
на самом деле это...
myPropertyChangedDelegate(this, EventArgs.Empty);
Таким образом, вы можете (очевидно) получить доступ только к переменной экземпляра частного делегата из класса объявления.
Соглашение должно предоставить что-то подобное в объявляющем классе.
protected virtual void OnMyPropertyChanged(EventArgs e)
{
EventHandler invoker = MyPropertyChanged;
if(invoker != null) invoker(this, e);
}
Затем вы можете вызвать OnMyPropertyChanged(EventArgs.Empty)
из любого места этого класса или ниже иерархии наследования для вызова события.
Ответ 3
Я предполагаю, что я не могу получить доступ к этим событиям так же, как другие унаследованные элементы?
Точно. Обычно для защищенной функции OnXyz
или RaiseXyz
для каждого события в базовом классе допускается повышение из унаследованных классов. Например:
public event EventHandler Loading;
protected virtual void OnLoading() {
EventHandler handler = Loading;
if (handler != null)
handler(this, EventArgs.Empty);
}
Вызывается в унаследованном классе:
OnLoading();
Ответ 4
Вы можете попробовать это, Он работает для меня:
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);
}
}