2013-03-13 53 views
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(); 

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

+1

您是否读过异常信息?它说什么? – Botz3000 2013-03-13 07:20:58

+0

@ Botz3000::),我知道你指向'对象引用',但是如果你无法获得虚拟覆盖行为,为什么虚拟覆盖可能在事件的第一位 – TalentTuner 2013-03-13 07:23:51

回答

1

事件的接口实际上只是一对方法,添加和删除。为自动实现的事件生成一个私人后台代理,只能通过事件名称在声明类中访问。

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

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

相关问题