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 を作成することを妨げるものは何もありません (すべてのハンドラーを実行すると仮定しても!)。

一般に、微妙な順序要件を持つイベント ハンドラーは、多くの場合、デバッグが困難なコードを作成する可能性があります。できれば避けたほうがいいです。ベース/派生の順序が重要な場合は、オーバーライドされたメソッドを使用してコードをより明確にし、派生型が適切な場所で MyBase を呼び出すようにすることができます。

于 2012-08-08T04:26:08.567 に答える