我看到了一些教程,我无法理解为什么他们建议从虚拟保护方法中提出事件,而不是直接,有什么区别?
public delegate void SomethingEventHandler(string s);
public event SomethingEventHandler Something;
public void Main() {
// Raising an event
OnSomething(); // Via method
Something("something"); // Directly
}
protected virtual void OnSomething()
{
Something("something");
}
答案 0 :(得分:9)
参见" 开发类库的设计指南",Event Design:
使用受保护的虚拟方法来引发每个事件。这仅适用于未密封类的非静态事件,而不适用于结构,密封类或静态事件。
遵守本指南允许派生类通过重写受保护的方法来处理基类事件。受保护的虚拟(Visual Basic中的可覆盖)方法的名称应与前缀为
On
的事件名称相同。例如,名为"TimeChanged"
的事件的受保护虚拟方法名为"OnTimeChanged"
。⚠重要
不需要覆盖受保护虚拟方法的派生类来调用基类实现。即使未调用其实现,基类也必须继续正常工作。
答案 1 :(得分:8)
我想这主要是因为一个名为'不要重复自己'(DRY)的基本原则。
例如:当属性值发生变化时,您必须引发NotifyPropertyChanged
事件。您希望从代码中的10个属性执行此操作。您可以重复从十种方法中提取该事件,或者调用一种方法为您执行此操作。如果你必须改变事件,你只需要做一次。
此外,使其protected virtual
使您有机会在派生类中覆盖该功能。
另请注意,对于线程安全,您的加注应如下所示:
protected virtual void OnSomething()
{
EventHandler d = Something;
if (d != null)
{
d("something");
}
}