2012-08-07 15 views
0

我有一个基类,一个继承自基类的中间类和一个继承自中间类的顶级类。我在基类中定义了一个事件并从一个方法中提取它。我在中间类中为基类事件定义了一个处理程序,并且在顶级类中也定义了相同的处理程序。 当事件触发时,中间类处理程序首先被击中,然后是顶级处理程序。固定的继承层次结构中的事件处理程序序列是否已修复?

如果我不断向链中添加更多类(超级继承顶级,超级继承等等),事件处理程序会不断在最基本的类中调用(例如,中,顶,超,至尊)。

这个序列总是成立吗? 如果不是,那么它会以不同的顺序排列?

我正在观察的顺序非常适合这个功能;我只是想确保它会一直工作。

我理解事件并不保证以任何顺序触发,但这是框架在编译时知道的事情,作为代码的作者,我可以说在运行时不会添加/删除委托这个事件,事件也不会在基地之外消耗,而且是子类连锁;事实上,它是受保护的。

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

编辑:我添加了样本,以澄清我在做什么。

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

如果您自己重新举办活动,并且没有任何代码可能会混淆再次提升它的方法,那么订单就不会受到干扰。当然,你应该使这种方法是私人的而不是保护,以获得硬性保证。 – 2012-08-07 17:15:19

+0

@Hans我添加了我的代码,所以你可以看到一切的范围。 – toddmo 2012-08-07 17:25:30

回答

1

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

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

观察我上面的警告:如果事件不是一个简单的事件,而是一个自定义事件,其中基类可以指定它自己的行为AddHandler和RaiseEvent,所有投注都关闭。没有任何东西可以阻止我创建自己的RaiseEvent,它以我想要的任意顺序运行处理程序(假设它甚至可以运行它们)!如果Base类不是您拥有的,那么如果您承担订购,我会小心。

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

+0

谢谢!我拥有基类,这将使我不必记得调用'MyBase.SayHello',再加上我可以使用鼠标来生成方法存根!哈!精彩!我会记得避免在表现不好的情况下订购要求。 – toddmo 2012-08-08 13:10:55