C#:如何引发继承事件?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (21)

我有一个基类,它包含以下事件:

public event EventHandler Loading;
public event EventHandler Finished;

在继承自此基类的类中,我试图引发事件:

this.Loading(this, new EventHandler()); // All we care about is which object is loading.

我收到以下错误:

The event 'BaseClass.Loading' can only appear on the left hand side of += or -= (BaseClass')

我假设我不能像其他继承的成员一样访问这些事件?

提问于
用户回答回答于

在基类中(在其中声明了事件),创建可用于引发事件的受保护方法:

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);
       }
   }
}

然后,在继承自此基类的类中,只需调用OnFined或onload方法来引发事件:

public AnotherClass : MyClass
{
    public void DoSomeStuff()
    {
        ...
        OnLoading(EventArgs.Empty);
        ...
        OnFinished(EventArgs.Empty);
    }
}
用户回答回答于

您只能访问声明类中的事件,因为.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)从该类中的任何位置或继承继承的以下位置调用事件。

扫码关注云+社区