与继承时订阅事件相反,何时应该重写OnEvent
时间:2020-03-06 14:59:39 来源:igfitidea点击:
以下什么时候应该做?
class Foo : Control { protected override void OnClick(EventArgs e) { // new code here } }
相对于此?
class Foo : Control { public Foo() { this.Click += new EventHandler(Clicked); } private void Clicked(object sender, EventArgs e) { // code } }
解决方案
覆盖而不是添加委托将使代码更有效,因此通常建议我们始终在可能的情况下执行此操作。有关更多信息,请参见此MSDN文章。这是一个相关的报价:
The protected OnEventName method also allows derived classes to override the event without attaching a delegate to it. A derived class must always call the OnEventName method of the base class to ensure that registered delegates receive the event.
该事件是针对外部订户的。当我们派生某些控件时,请始终重写OnEvent方法,而不是订阅事件。这样,我们可以确定何时调用代码,因为在调用base.OnEvent()时会触发实际事件,并且可以在代码之前,代码之后,代码中间或者不在代码中间调用此事件。全部。然后,我们还可以对事件的返回值(即EventArgs对象中的更改属性)做出反应。
如果我们像Kent Boogaart的注释那样覆盖,则需要谨慎地回调base.OnClick以允许调用事件订阅
继承的类永远不要订阅自己的事件或者基类的事件。
现在,如果一个类中包含另一个不同类的实例,则它可以使用该类的事件,并确定是否应该引发它自己的事件。
例如,我最近推出了一个MRU List类。其中包含许多ToolStripMenuItem控件,我使用了它们的click事件。在点击事件被消耗之后,我随后提出了班级的事件。 (请参见此处的源代码)
订阅事件旨在使控件监视其他控件上的事件。对于监视我们自己的事件,OnClick很好。但是请注意,Control.OnClick会处理触发这些订阅的事件,因此请确保在替代中调用它。
请注意(至少在.NET 2.0中),我在框架中(特别是在DataTable类中)找到了几个地方,只有在处理了相应的Foo事件后才调用OnFoo方法!这违反了框架设计准则,但我们坚持使用它。
我已经通过在类中某个地方的虚拟处理程序处理事件来解决它,例如:
public class MyDataTable : DataTable { public override void EndInit() { base.EndInit(); this.TableNewRow += delegate(object sender, DataTableNewRowEventArgs e) { }; } protected override void OnTableNewRow(DataTableNewRowEventArgs e) { base.OnTableNewRow(e); // your code here } }