|
2019/06/30(Sun) 07:08:07 編集(投稿者)
■No91453 (エベェ さん) に返信 > この処理で > 「■イベント1(SHOWN)」 と 「■イベント2(onSHOWN)」 を分ける意味がわかりません > 「■イベント1(SHOWN)」に「●処理1」と「●処理3」をまとめても同じ結果になるのでしょうか
そのクラスを継承する場合に差異が生じることになりますね。 (継承を想定していないクラスなら、NotInheritable なクラスとして宣言すべきです)
> またon〜 どいういった場合に使われるものなのでしょうか
そもそも『Sub Onイベント名( e As EventArgs派生クラス )』なメソッドは、 多くの場合、Protected Overidable な (あるいは単に Protected な)メソッドとして実装されます。 これは、自身が持つイベントを継承先で発生させるために設けられます。
たとえば……クラスが自身のイベントを発生させるために、 RaiseEvent というステートメントが使われますよね。
もしも自作クラスに Code プロパティが設けられていて、 それが変更された時に CodeChanged イベントを発生させたいとしたら、 このようなコードを書くことができます。
Public Event CodeChanged As EventHandler Public Property Code() As String Get Return _Code End Get Set(value As String) If _Code <> value Then _Code = value RaiseEvent CodeChanged(Me, EventArgs.Empty) End If End Set End Property Private _Code AS String
ところがこのような実装ですと、このクラスを継承した新たなクラスを作成する際に都合が悪くなります。 具体的にはこのようなケースです。
「派生クラスから、基本クラスの CodeChanged イベントを意図的に発生させることができない」 「Code が変更された時に、CodeChanged が呼ばれる前に別の処理を割り込ませることができない」 「イベントを発生させることなく Code を書き換える方法が提供されていない」
そこで、イベントを提供するクラスでは、そのイベントを直接 RaiseEvent するのではなく、 RaiseEvent するためのメソッドを設け、それを通じて呼び出されるように実装するのが一般的です。
Protected Overridable Sub OnCodeChanged(e As EventArgs) RaiseEvent CodeChanged(Me, EventArgs.Empty) End Sub
Public Property Code() As String Get Return _Code End Get Set(value As String) If _Code <> value Then _Code = value OnCodeChanged(EventArgs.Empty) End If End Set End Property
---
このようにデザインしておけば、このクラスを継承する側では、 継承元の Protected Overridable Sub OnCodeChanged(e As EventArgs) を 継承した Protected Overrides Sub OnCodeChanged(e As EventArgs) を通じて、 イベントの発生タイミングを調整することができるというわけです。
派生クラスから、基本クラスの CodeChanged イベントを意図的に発生させるために RaiseEvent MyBase.CodeChanged(Me, EventArgs.Empty) と書くことは文法上許容されていませんが、On何某が用意されていれば、 OnCodeChanged(EventArgs.Empty) と書くことで、基本クラスのイベントを意図的に発生させることができます。
Code が変更された時に、CodeChanged が呼ばれる前に別の処理を割り込ませるために、 Protected Overrides Sub OnCodeChanged(e As EventArgs) DoAnything() MyBase.OnCodeChanged(e) End Sub のように実装したり、Code を書き換える際のイベントの発生を抑制するために Protected Overrides Sub OnCodeChanged(e As EventArgs) If CanRaiseEvents Then MyBase.OnCodeChanged(e) End If End Sub のような条件分岐を行うといったカスタマイズが可能になります。
https://docs.microsoft.com/ja-jp/dotnet/standard/events/
》 通常、イベントを発生させるには、 》 protected や virtual (C# の場合)、または 》 Protected や Overridable (Visual Basic の場合) として 》 マークされたメソッドを追加します。
》 このメソッドには OnEventName の形式で名前を付けます (OnDataReceived など)。
》 メソッドでは、イベント データ オブジェクトを指定するパラメーターを 1 つ受け取る必要があります。 》 これは、EventArgs 型または派生型のオブジェクトです。
》 このメソッドを指定すると、イベントを発生させるためのロジックを 》 派生クラスでオーバーライドできます。
》 派生クラスは常に基底クラスの OnEventName メソッドを呼び出して、 》 登録されたデリゲートがイベントを必ず受信できるようにします。
|