我有一个基类,一个继承自基类的中间类,以及一个继承自中产阶级的顶级类。我在基类中定义了一个事件,并从一个方法中引出它。我在中间类中为基类事件定义了一个处理程序,并在顶级类中定义了相同的处理程序。 当事件触发时,中间类处理程序首先被击中,然后是顶级处理程序。
如果我继续向链中添加更多类(超级继承自top,supreme继承自ultra等),事件处理程序将首先在最基本的类中被调用(例如,中间,顶部,超,最高)
这个序列总是有效吗? 如果没有,那么它可能/将会以不同的顺序发生什么?
我观察的顺序非常适合这个功能;我只是想确保它能够始终如一地工作。
我理解事件不能保证以任何顺序触发,但这是框架在编译时知道的东西,并且作为代码的作者,我可以说在运行时不会为此添加/删除委托事件,也不会在基地之外和它的子类链上消费;事实上,它受到了保护。
我不知道幕后会发生什么,但也许它会在编译期间设置序列,因此在运行时它是完成交易?
编辑:我正在添加样本以清楚我正在做的事情。
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
答案 0 :(得分:1)
在您的特定代码示例中,订单将按预期运行。
当你有一个被标记为Handles Me....
的方法时,所有VB编译器都会在构造函数的最开头粘贴一个隐藏的AddHandler语句。构造函数从基类型运行到派生类型,因此基类型的隐藏AddHandler将在派生类型中的AddHandler之前运行。 只要您的RaiseEvent按照添加处理程序的顺序引发事件,那么是的,您将看到您现在看到的顺序。对于像你这样的简单VB事件,这种行为极不可能改变。
观察我上面的警告:如果事件不是一个简单的事件,而是一个自定义事件,其中基类可以为AddHandler和RaiseEvent指定它自己的行为,所有的注意都是关闭的。没有什么能阻止我制作我自己的RaiseEvent,它以我想要的任何随机顺序运行处理程序(假设它甚至全部运行它们!)如果Base类不是你拥有的东西,我会小心你假设订购。
通常,具有微妙排序要求的事件处理程序通常可以创建难以调试的代码位。如果可以的话,最好避免。如果基本/派生顺序很重要,您可以通过使用重写方法使代码更清晰,并且派生类型在适当的位置调用MyBase。