什么时候应该覆盖OnEvent,而不是在继承时订阅事件

时间:2008-10-01 19:33:50

标签: c# .net override

何时应该做以下事情?

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
    }
}

7 个答案:

答案 0 :(得分:9)

覆盖而不是附加委托将导致更高效的代码,因此通常建议您始终尽可能地执行此操作。有关更多信息,请参阅this MSDN article。这是一个相关的引用:

  

受保护的OnEventName方法也是   允许派生类重写   没有附加委托的事件   它。派生类必须始终调用   基础的OnEventName方法   上课确保注册   代表们会收到这个活动。

答案 1 :(得分:8)

该活动适用于外部订阅者。在派生某些控件时,始终覆盖OnEvent方法而不是订阅该事件。这样,您可以确定何时调用代码,因为当您调用base.OnEvent()时会触发实际事件,并且您可以在代码之前,代码之后,代码中间或之后调用此实例。所有。然后,您还可以对事件的返回值做出反应(即EventArgs对象中已更改的属性)。

答案 2 :(得分:3)

请注意(至少在.NET 2.0中)我在框架中找到了一些位置(特别是在DataTable类中),当相应的Foo事件具有相同的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
    }
}

答案 3 :(得分:0)

如果你覆盖像Kent Boogaart评论那么你需要小心回调base.OnClick以允许调用事件订阅

答案 4 :(得分:0)

继承的类永远不应该订阅它自己的事件,或它的基类'事件。

现在,如果一个类中有另一个不同的类的实例,那么它可以使用该类的事件,并确定它是否应该引发它自己的事件。

例如,我最近推出了一个MRU List课程。在其中,有许多ToolStripMenuItem控件,我使用了它的click事件。在点击事件被消耗之后,我然后提出了我的课程的事件。 (see that source code here

答案 5 :(得分:0)

订阅该事件旨在用于监视不同控件上的事件的控件。监控自己的事件OnClick很好。但请注意,Control.OnClick处理触发那些订阅的事件,因此请务必在覆盖中调用它。

答案 6 :(得分:0)

值得注意的是,在某些特殊情况下,它仅适用于处理程序,不适用于OnEvent覆盖。这样的例子之一-

Why style is not applied when I'm removing StartupUri in WPF?