重写的方法更可取,因为它将被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
是更好的实现方式,原因如下:Bar
必须执行以下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)
我们必须创建一个处理方法的委托,一个EventHandler
实例,然后调用基类中事件的add_Changed
方法。虽然这些不会影响性能,但先前的代码对Baz
来说都不是必需的。由于对OnChanged
的任何调用都将是虚拟的,所以唯一的性能代价将是CLR在继承链中查找正确的实例方法以调用。