C#中事件处理的首选方法是什么?
在.NET中处理事件的首选/推荐方法是:C#中事件处理的首选方法是什么?,c#,winforms,event-handling,C#,Winforms,Event Handling,在.NET中处理事件的首选/推荐方法是: this.Load += new EventHandler(Form1_Load); private void Form1_Load(object sender, EventArgs e) { } 或 protected override void OnLoad(EventArgs e) { base.OnLoad(e); } 每种方法的优缺点是什么?多年来,我一直在使用这两种方法,通常更倾向于使用第一种方法,因为VisualStudio会自
this.Load += new EventHandler(Form1_Load);
private void Form1_Load(object sender, EventArgs e)
{ }
或
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
}
每种方法的优缺点是什么?多年来,我一直在使用这两种方法,通常更倾向于使用第一种方法,因为VisualStudio会自动创建用于处理事件的方法。但是,第二个方法是否有我所缺少的好处?重写的方法更可取,因为它将被CLR以多态方式虚拟调用 [编辑]以下是我认为重写方法更可取的原因: 下面是一个简单的例子:
class Foo
{
public event EventHandler Changed = delegate { };
protected virtual void OnChanged()
{
this.Changed(this, EventArgs.Empty);
}
}
class Bar : Foo
{
public Bar()
{
this.Changed += new EventHandler(this.Bar_Changed);
}
void Bar_Changed(Object sender, EventArgs e) { }
}
class Baz : Foo
{
protected override void OnChanged()
{
base.OnChanged();
}
}
现在我相信Baz
是更好的实现,原因如下<代码>条形图必须按照以下IL说明连接事件:
L_000a: ldftn instance void Bar::Bar_Changed(object, class [mscorlib]System.EventArgs)
L_0010: newobj instance void [mscorlib]System.EventHandler::.ctor(object, native int)
L_0015: call instance void Foo::add_Changed(class [mscorlib]System.EventHandler)
我们必须为handling方法创建一个委托,
EventHandler
的一个实例,然后在基类中对事件调用add\u Changed
方法。虽然这些都不是性能杀手,Baz
工作不需要前面的代码。由于对OnChanged的的任何调用都是虚拟的,因此唯一的性能损失将是CLR在继承链中找到要调用的正确实例方法。这完全取决于您希望捕获事件的位置和原因
第一种方法(wire-up)用于当您希望其他类处理事件时。你可能需要这样做的原因有很多;另一个类可以访问执行某些复杂逻辑或其他功能的服务。关键是,当您需要一个单独的观察者响应事件时,可以使用第一种方法
第二种方法(重写)用于希望窗体响应的时间,因为它可以;因为它的责任是地方性的 第一种方法是微软的建议。模式是:
一些代码想要引发一个事件,调用OnXxx
OnXxx向代表打电话
调用有线事件处理程序
如果执行第二个模型,您可能会忘记base.OnXxx调用并破坏一切。选项2很好的一部分是,您可以决定是在所有其他事件处理程序之前还是之后调用您。如果将代码放在base.OnXxx之前,则会在事件执行之前执行。当然,第一个模型总是可以使用的,第二个模型只有在对引发事件的类进行子类化时才可以使用。虽然不是最初的问题,但我想指出:
this.Load += new EventHandler(Form1_Load);
可以写为:
this.Load += Form1_Load;
代理结构是推断出来的。没有硬性规定,但这两种方法都有缺陷。你可以选择一个你可以很容易避免的
代表
许多开发人员将+=代码放在可以重复调用的地方。至少很多新手都是这样做的。因此,所有者控件维护的委托列表中将有“n”个条目,所有条目都将被调用。避免这种情况的简单方法是将+=调用放在只调用一次的构造函数中
OnXXXX
风险在于忘记调用base.XXX方法。这是一个常见的bug源,如果您没有调用基类版本,大多数Windows程序员都会意识到问题所在——这对于Windows消息(paint等)来说尤其如此 说得好,我忘了处理事件的其他事情。在窗体处理它自己的事件的情况下,为什么VS连接事件处理程序而不是使用受保护的重写?您必须询问MS关于该决定的问题。我真的不知道。你能进一步解释一下吗?我不确定我是否理解你的意思。@DK:风格问题。我更喜欢“这个”,但很多人不喜欢,这很好。