使用事件处理程序还是覆盖事件触发方法

25

我正在创建一个Button的子类,想要在一些事件(例如OnClick)中添加特定功能。哪种方法更可取?我应该覆盖OnClick吗?

protected override void OnClick(EventArgs e)
{
    base.OnClick(e);
    doStuff();
}

或者我应该通过设计器将OnClick事件链接到我的Button子类中定义的事件处理程序?

class ButtonSubclass
{
    public ButtonSubclass() : base()
    {
        InitializeComponent();
    }

    private void InitializeComponent()
    {
        this.Click += new System.EventHandler(this.ButtonSubclass_Click);
    }
}

编辑:我进行了轻微的视觉更改(可能会被视为基本的皮肤),但大部分更改都在事件处理程序中,我不想在每个重用它的表单上重新实现(复制粘贴)。

4个回答

28

如果您真正专注于按钮,则覆盖 OnClick 是有意义的。 如果您只是在实际更改单击按钮时发生的情况,我首先不会子类化 Button - 我会只是添加事件处理程序。

编辑:为了给出更多想法-如果您想要为多个按钮添加类似的事件处理程序,则很容易编写一个实用方法来执行此操作,并从多个位置调用它。 它不需要实际的子类化。 当然,这并不是说在您的情况下子类化一定是错误的-只是给您提供额外选择 :)


1
在这个上下文中,你能解释一下“specializing”的含义吗? - MasterMastic
@Ken:让它以一种真正不同的方式运作,例如按相反的顺序执行所有处理程序。不仅仅是“一个始终具有特定处理程序的按钮”。 - Jon Skeet
我喜欢这个答案,然而 - 当一个人在 .net 中制作更专业的表单时,鼓励捕获 onclick 事件、onload 事件。 - timothy
其实这一切都是关于重用的。无论是覆盖方法还是实现事件,在这两种情况下,您都在专门化行为。如果您想更改按钮的行为并重用整个按钮以期望它以新的方式运行,则覆盖;否则,捕获事件并实现,使按钮在下一次使用时保持不变。 - timothy

7

继承时一定要重写 OnClick 方法,这样可以提高性能。


4
在大多数情况下,可读性应被视为次要重要性,直到影响被证明是显著的。我不认为在这里性能的差异很大(它相当小,而且我们谈论的是按钮点击,即相对不频繁的事件)。 - Jon Skeet
我并不是说重写 OnClick 是错误的 - 只是性能不是这样做的原因。 - Jon Skeet
也许性能提升微不足道,但如果您已经在进行子类化以实现其他目的而不仅仅是覆盖 OnClick,则我认为这样做更易于阅读、实现速度更快,而且您可以“免费”获得性能提升。 - Jakob Christensen
因此,提供这些原因是为了“更易于阅读,更快速地实现”,而不是“它可以提供更好的性能”。那就是我的观点。性能增益是附带的。 - Jon Skeet
如果UI元素被多次实例化,那么添加一个额外的事件处理程序会显著影响性能,例如在ItemsControl中。 - l33t
您正在重复执行相同的代码多次。这样做有什么好处可以提高性能吗? - Blessed Geek

0
实际上,将事件处理程序附加到方法中有一个优点。您的事件处理程序是私有的,而覆盖的方法必须使用预定义名称进行保护。如果您使用混淆/加密工具来保护您的应用程序,当您的代码使用protected override时比使用private更容易暴露。

请解释一下,我的代码已编译完成。为什么一个私有成员比一个受保护的成员更安全?您的意思是私有成员的代码不可见,受保护的代码是可见的吗? - Blessed Geek

-2
对于按钮点击,我会将其保留为读取方法。但我想这是个人偏好的问题。我很想看看大家的共识是什么。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接