0

考虑下面的场景,可能这个场景是非常假设的

public delegate void MyDel();

public class T1
{
    public T1()
    {

    }
    public virtual event MyDel MyEvent;

    public virtual void RaiseEvent()
    {
        MyEvent();
     }

    protected virtual void HandleEvent()
    {
        MessageBox.Show("base event");

    }
}

public class T2:T1
{
    public override event MyDel MyEvent;

    public T2()
    {
        MyEvent += new MyDel(HandleEvent);

    }

    protected override void HandleEvent()
    {
        MessageBox.Show("overridden event");
    }
}

和主要客户代码

        baseT = new T2();
        baseT.MyEvent += new MyDel(() => MessageBox.Show("From client"));
        baseT.RaiseEvent(); 

为什么它会抛出异常,为什么虚拟事件的行为不像虚拟/覆盖方法?

4

1 回答 1

1

事件的接口实际上只是一对方法,添加和删除。为自动实现的事件生成一个私有支持委托,该委托只能在声明类内部通过事件名称进行访问。

事件的 virtual 关键字仅适用于 add/remove 方法对。对于自动实现的事件,支持委托的访问和调用不是虚拟的。当订阅发生在派生类 ( T2) 的实例上时,它使用的是重写的添加/删除方法,这些方法使用自己的支持委托。基类的支持委托仍为 null,并且仍在RaiseEvent. 这会导致NullReferenceException何时RaiseEvent调用。

虚拟活动很少见。我可能会使事件本身成为非虚拟的,并使用受保护的虚拟方法来允许派生类修改事件的行为。

于 2013-03-13T07:32:17.653 回答