为什么虚拟事件不会调用重写的处理程序

时间:2013-03-13 07:18:01

标签: c# events

考虑以下情况,可能这种情况非常假设

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

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

1 个答案:

答案 0 :(得分:1)

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

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

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