以下是我用于测试的程序.它打印(如预期):
Raise A Event from A Raise B Event from B
现在,如果我们改变Main的前两行是:
A a = new B(); B b = new B();
该计划将打印:
Raise A Raise B Event from B
这也是预期的,因为重写事件会隐藏基类中的私有支持字段,因此基类触发的事件对派生类的客户端不可见.
现在我将相同的行改为:
B b = new B(); A a = b;
程序开始打印:
Raise A Raise B Event from A Event from B
这是怎么回事?
class A { public virtual event EventHandler VirtualEvent; public void RaiseA() { Console.WriteLine("Raise A"); if (VirtualEvent != null) { VirtualEvent(this, EventArgs.Empty); } } } class B : A { public override event EventHandler VirtualEvent; public void RaiseB() { Console.WriteLine("Raise B"); if (VirtualEvent != null) { VirtualEvent(this, EventArgs.Empty); } } } class Program { static void Main(string[] args) { A a = new A(); B b = new B(); a.VirtualEvent += (s, e) => Console.WriteLine("Event from A"); b.VirtualEvent += (s, e) => Console.WriteLine("Event from B"); a.RaiseA(); b.RaiseB(); } }
Jon Skeet.. 12
我们有一个(B)实例,它有以下几个字段:
A.VirtualEvent:null
B.VirtualEvent:两个事件处理程序
调用a.RaiseA()
只打印"提升A" - 但仅此而已,因为A中的私有字段为空.
b.RaiseB()
打印剩余的三行的调用,因为事件已订阅两次(一次打印"来自A的事件",一次打印"来自B的事件").
这有帮助吗?
编辑:更清楚 - 将虚拟事件视为一对虚拟方法.它非常像这样:
public class A { private EventHandler handlerA; public virtual void AddEventHandler(EventHandler handler) { handlerA += handler; } public virtual void RemoveEventHandler(EventHandler handler) { handlerA -= handler; } // RaiseA stuff } public class B : A { private EventHandler handlerB; public override void AddEventHandler(EventHandler handler) { handlerB += handler; } public override void RemoveEventHandler(EventHandler handler) { handlerB -= handler; } // RaiseB stuff }
现在更清楚了吗?它不是很一样,因为据我所知,你不能覆盖只是一个事件的"部分"(即的方法之一),但它给出了正确的总体印象.
我们有一个(B)实例,它有以下几个字段:
A.VirtualEvent:null
B.VirtualEvent:两个事件处理程序
调用a.RaiseA()
只打印"提升A" - 但仅此而已,因为A中的私有字段为空.
b.RaiseB()
打印剩余的三行的调用,因为事件已订阅两次(一次打印"来自A的事件",一次打印"来自B的事件").
这有帮助吗?
编辑:更清楚 - 将虚拟事件视为一对虚拟方法.它非常像这样:
public class A { private EventHandler handlerA; public virtual void AddEventHandler(EventHandler handler) { handlerA += handler; } public virtual void RemoveEventHandler(EventHandler handler) { handlerA -= handler; } // RaiseA stuff } public class B : A { private EventHandler handlerB; public override void AddEventHandler(EventHandler handler) { handlerB += handler; } public override void RemoveEventHandler(EventHandler handler) { handlerB -= handler; } // RaiseB stuff }
现在更清楚了吗?它不是很一样,因为据我所知,你不能覆盖只是一个事件的"部分"(即的方法之一),但它给出了正确的总体印象.