>我有一个基类,一个从基类继承的中产阶级,以及一个从中产阶级继承的顶级类。我在基类中定义了一个事件,并从方法中引发它。我在中级阶级中为基类事件定义了一个处理程序,并在顶级类中定义了相同的处理程序。当事件触发时,首先命中中类处理程序,然后命中顶级类处理程序。
如果我不断向链中添加更多类(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
在您的特定代码示例中,顺序将按您的预期方式运行。
当你有一个标记为Handles Me....
的方法时,VB编译器所做的只是在构造函数的最开头粘贴一个隐藏的AddHandler语句。构造函数从基类型运行到派生类型,因此基类型的隐藏 AddHandler 将在派生类型中的 AddHandler 之前运行。只要您的 RaiseEvent 按照添加处理程序的顺序引发事件,那么是的,您将看到现在看到的顺序。对于像您这样的简单 VB 事件,该行为极不可能改变。
请注意我上面的警告:如果事件不是一个简单的事件,而是一个自定义事件,基类可以在其中为 AddHandler 和 RaiseEvent 指定自己的行为,则所有赌注都已关闭。没有什么能阻止我制作自己的 RaiseEvent 以我想要的任何随机顺序运行处理程序(假设它甚至运行所有处理程序!如果基类不是你拥有的东西,如果你假设排序,我会很小心。
通常,具有细微排序要求的事件处理程序通常可以创建难以调试的代码位。如果可以的话,最好避免。如果基/派生排序很重要,则可以通过使用重写的方法使代码更清晰,并使派生类型在适当的位置调用 MyBase。