考虑以下情况,可能这种情况非常假设
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();
为什么会抛出异常,为什么虚拟事件的行为不像虚拟/重写方法?
答案 0 :(得分:1)
事件的界面实际上只是一对方法,添加和删除。为自动实现的事件生成私有支持委托,该事件只能通过事件名称在声明类内部访问。
事件的虚拟关键字仅适用于添加/删除方法对。对于自动实现的事件,访问和调用支持委托不是虚拟的。当订阅发生在派生类(T2
)的实例上时,它使用重写的添加/删除方法,这些方法使用自己的支持委托。基类的支持委托仍为空,仍在RaiseEvent
中调用。这会在NullReferenceException
被调用时导致RaiseEvent
。
虚拟事件很少见。我可能会使事件本身非虚拟,并使用受保护的虚方法来允许派生类修改事件的行为。