1

我有一个基类,一个从基类继承的中间类,以及一个从中间类继承的顶级类。我在基类中定义了一个事件并从一个方法中引发它。我在中间类中为基类事件定义了一个处理程序,也在顶级类中定义了相同的处理程序。当事件触发时,中间类处理程序首先被击中,然后是顶级处理程序。

如果我继续向链中添加更多类(ultra 继承自 top,supreme 继承自 ultra 等),事件处理程序会首先在最基本的类中被调用(例如,middle、top、ultra、supreme)。

这个序列总是成立吗?如果没有,什么可以/会使它以不同的顺序运行?

我观察的顺序非常适合这个功能;我只是想确保它能够始终如一地工作。

我知道事件不能保证以任何顺序触发,但这是框架在编译时知道的,作为代码的作者,我可以说在运行时不会为此事件添加/删除委托,也不会该事件是否会在基础及其子类链之外被消耗;事实上,它受到保护。

我不知道幕后发生了什么,但也许它在编译期间设置了序列,因此在运行时它已经完成了?

编辑:为了清楚我在做什么,我正在添加示例。

Public Class BaseClass

  Protected Event Hello(ByRef Cancel As Boolean)

  Public Sub SayHello()
    Dim Cancel As Boolean
    RaiseEvent Hello(Cancel)
  End Sub

End Class

Public Class MiddleClass
  Inherits BaseClass

  Private Sub MiddleClass_Hello(ByRef Cancel As Boolean) Handles Me.Hello
    'This appears to always get called first
  End Sub

End Class

Public Class TopClass
  Inherits MiddleClass

  Private Sub TopClass_Hello(ByRef Cancel As Boolean) Handles Me.Hello
    'This appears to always get called second
  End Sub

End Class

Public Class UltraClass
  Inherits TopClass

  Private Sub UltraClass_Hello(ByRef Cancel As Boolean) Handles Me.Hello
    'This appears to always get called third
  End Sub

End Class

'...and so on
4

1 回答 1

1

在您的特定代码示例中,订单将按照您的预期行事。

当您有一个标记为 的方法时,Handles Me....VB 编译器所做的所有事情就是在构造函数的最开始处粘贴一个隐藏的 AddHandler 语句。构造函数从基类型运行到派生类型,因此基类型的隐藏 AddHandler 将在派生类型中的 AddHandler 之前运行。只要您的 RaiseEvent 是按照添加处理程序的顺序引发事件,那么是的,您会看到现在看到的顺序。对于像您这样的简单 VB 事件,这种行为极不可能改变。

请注意我上面的警告:如果事件不是一个简单的事件,而是一个自定义事件,其中基类可以为 AddHandler 和 RaiseEvent 指定它自己的行为,那么所有的赌注都没有了。没有什么能阻止我制作自己的 RaiseEvent 以我想要的任何随机顺序运行处理程序(假设它甚至运行所有处理程序!)如果 Base 类不是你拥有的东西,如果你假设排序,我会小心。

通常,具有细微排序要求的事件处理程序通常会创建难以调试的代码位。如果可以,最好避免。如果基/派生的顺序很重要,您可以通过使用重写的方法使代码更清晰,并让派生类型在适当的位置调用 MyBase。

于 2012-08-08T04:26:08.567 回答