Avoid duplicated event handlers?
How do I avoid an event from being handled twice (if is the same handler?)
Module Module1
Sub Main()
Dim item As New Item
AddHandler item.TitleChanged, AddressOf Item_TitleChanged
AddHandler item.TitleChanged, AddressOf Item_TitleChanged
item.Title = "asdf"
Stop
End Sub
Priva开发者_Go百科te Sub Item_TitleChanged(sender As Object, e As EventArgs)
Console.WriteLine("Title changed!")
End Sub
End Module
Public Class Item
Private m_Title As String
Public Property Title() As String
Get
Return m_Title
End Get
Set(ByVal value As String)
m_Title = value
RaiseEvent TitleChanged(Me, EventArgs.Empty)
End Set
End Property
Public Event TitleChanged As EventHandler
End Class
Output:
Title changed!
Title changed!
Desired output:
Title changed!
I want the event manager to detect that this event is already handled by this handler and so it shouldn't rehandle (or readd) it.
You can also just always call RemoveHandler
before AddHandler
. I have found this practical in specific scenarios.
Wrapping the event handler list in a HashSet
will make sure the handlers are not duplicate references, the following snippet replacement for the question's Item
class will work under the above sample (it won't re-add the handler if it's already in the HashSet
):
Public Class Item
Private m_Title As String
Public Property Title() As String
Get
Return m_Title
End Get
Set(ByVal value As String)
m_Title = value
RaiseEvent TitleChanged(Me, EventArgs.Empty)
End Set
End Property
Private handlers As New HashSet(Of EventHandler)
Public Custom Event TitleChanged As EventHandler
AddHandler(value As EventHandler)
handlers.Add(value)
End AddHandler
RemoveHandler(value As EventHandler)
handlers.Remove(value)
End RemoveHandler
RaiseEvent(sender As Object, e As System.EventArgs)
For Each handler In handlers.Where(Function(h) h IsNot Nothing)
handler(sender, e)
Next
End RaiseEvent
End Event
End Class
精彩评论