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

J. *_*Doe 5 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");
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*exD 9

请参阅" 事件设计:开发类库的设计指南 " :

使用受保护的虚拟方法来引发每个事件.这仅适用于未密封类的非静态事件,而不适用于结构,密封类或静态事件.

遵循此准则允许派生类通过重写受保护的方法来处理基类事件.受保护的虚拟(Visual Basic中的Overridable)方法的名称应与前缀为的事件名称相同On.例如,命名的事件的受保护虚拟方法"TimeChanged"已命名"OnTimeChanged".

重要

不需要覆盖受保护的虚方法的派生类来调用基类实现.即使未调用其实现,基类也必须继续正常工作.


Pat*_*man 8

我想这主要是因为一个叫做"不要重复自己"(DRY)的基本原理.

例如:您必须NotifyPropertyChanged在属性值发生更改时引发事件.您希望从代码中的10个属性执行此操作.您可以重复从十种方法中提取该事件​​,或者调用一种方法为您执行此操作.如果你必须改变事件,你只需要做一次.

此外,通过它protected virtual,您可以在派生类中覆盖该功能.

另请注意,对于线程安全,您的加注应如下所示:

protected virtual void OnSomething() 
{
     EventHandler d = Something;

     if (d != null)
     {
         d("something");
     }    
}
Run Code Online (Sandbox Code Playgroud)

  • 您可以将其简化为"Something?.Invoke("something");`(在C#6中) (6认同)
  • 那是真实的。尽管以上内容对于不了解所有C#6语法的新程序员可能更好。 (2认同)