从Protected Virtual Void方法或直接提升事件有什么不同?

时间:2016-01-10 11:16:27

标签: c# events

我看到了一些教程,我无法理解为什么他们建议从虚拟保护方法中提出事件,而不是直接,有什么区别?

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");
}

2 个答案:

答案 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");
     }    
}