イベントとデリゲート。

以前のエントリ(こことか、ここ。)でこんなクラスを書きました。


[Visual Basic]

Imports System
Imports System.Collections.Generic


' ジェネリッククラスであることに何の意味も無いけど。
Public Class Folder(Of T)


Private _value As T

Public Property Value() As T
Get
Return
_value
End Get
Set(ByVal value As T)
_value = value
' イベントを発生させる。
RaiseEvent ValueUpdated(Me, New EventArgs)
End Set
End Property


Public Event ValueUpdated(ByVal sender As Object, ByVal e As EventArgs)


End Class

いまさらながらちょっと気になったところが。
というのは、イベントとデリゲートってセットで話されてるコメントをいただいたり、「デリゲートを理解してからイベントね」ってお話もいただいているにもかかわらず、イベントの構文にデリゲートが出てこない・・・。
なじぇ!?ということで目をつけたのが、

[Visual Basic]

Public Event ValueUpdated(ByVal sender As Object, ByVal e As EventArgs)

この部分↑。senderとか、eとかイべントハンドラの引数になる部分が書かれているし。なんかはしょられてるっぽい・・・。
この部分はMSDN:イベントをクラスに追加するを見てこう書けばいいのね〜って思ってそのまま書いていたんだけど実はよくわかっていなかったです。

これをどうすればデリゲートに出来るか・・・。


[Visual Basic]

Imports System
Imports System.Collections.Generic


' ジェネリッククラスであることに何の意味も無いけど。
Public Class Folder(Of T)


Private _value As T

Public Property Value() As T
Get
Return
_value
End Get
Set(ByVal value As T)
_value = value
' イベントを発生させる。
RaiseEvent ValueUpdated(Me, New EventArgs)
End Set
End Property

' ValueUpdatedDelegate型のイベントを宣言。
Public Event ValueUpdated As ValueUpdatedDelegate


End Class

' デリゲートを宣言。
Public Delegate Sub ValueUpdatedDelegate(ByVal sender As Object, ByVal e As EventArgs)

そんでもってイベントの登録のときに AddHandler を使ったパターンを試したんだけど、そのときのインテリセンス↓をあまり見ていなかったのが致命的。

Addhandler Object As Event, Object As Delegate
デリゲート指定してるぢゃないですか!
つまり、前回書いた、

[Visual Basic]

Imports System
Imports System.Collections.Generic


Public Class EventHandleTestClass


Private eventSender As New Folder(Of Object)


Public Sub New()

' AddHandler で動的にイベントハンドラを追加するさ。
AddHandler eventSender.ValueUpdated, AddressOf Me.eventSender_ValueUpdated

End Sub


Private Sub eventSender_ValueUpdated(ByVal sender As Object, ByVal e As EventArgs)

Console.WriteLine("ハンド!ハンド!今絶対手で触ったって!")

End Sub


End Class

は、

[Visual Basic]

Imports System
Imports System.Collections.Generic


Public Class EventHandleTestClass


Private eventSender As New Folder(Of Object)


Public Sub New()

' 先にデリゲート作っておいてさ、
Dim eventHandler As New ValueUpdatedDelegate(AddressOf Me.eventSender_ValueUpdated)

' AddHandler で追加するよ。
AddHandler eventSender.ValueUpdated, eventHandler

End Sub


Private Sub eventSender_ValueUpdated(ByVal sender As Object, ByVal e As EventArgs)

Console.WriteLine("ハンド!ハンド!今絶対手で触ったって!")

End Sub


End Class

こんな感じでもいける♪なるほど〜。やっとデリゲートとイベントだw