homelinksBlijf op de hoogte van de recente aanpassingen op vbvoorbeelden!
Visual Basic 2010 Voorbeelden

visual basic 2010 broncode voorbeelden

Microsoft Visual Studio 2010Microsoft Developers Network - Visual BasicMicrosoft .NET Framework

24.3. Events versus Delegates

Print Email Deel op Facebook Deel op Twitter

Dit artikel is gepubliceerd op zondag 31 juli 2011 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.

Bij een optreden van een event van een eventsource worden de - aan deze event gekoppelde - eventhandlers uitgevoerd.  Dit kan doordat de eventsource objecten delegates bijhouden van de methods ( eventhandlers ) die worden uitgevoerd bij het optreden van een event.
Bij het "raisen" van de event, zullen de delegates naar de eventhandlers worden geïnvokeerd.

De conclusie is dat events delegates zijn.  Events zijn slechts een taalconstructie die achter de schermen worden omgezet naar delegates.

Onderstaand voorbeeld illustreert hoe deze omzetting kan gebeuren.
Visual Basic 2010 Broncode
Namespace UsingEvents
    Class SomeEventSource
        Public Event SomeEvent()
        Public Sub RaiseSomeEvent()
            RaiseEvent SomeEvent()
        End Sub
    End Class
End Namespace
Omgezet naar :
Visual Basic 2010 Broncode
Namespace UsingDelegates
    Class SomeEventSource
        Public Delegate Sub SomeEventHandler()
        Private m_SomeEvent As SomeEventHandler
        Public Sub add_SomeEvent(ByVal obj As SomeEventHandler)
            m_SomeEvent = _
                        DirectCast(System.Delegate.Combine(m_SomeEvent, obj),  _
                                   SomeEventHandler)
        End Sub
        Public Sub remove_SomeEvent(ByVal obj As SomeEventHandler)
            m_SomeEvent = _
                        DirectCast(System.Delegate.Remove(m_SomeEvent, obj),  _
                                   SomeEventHandler)
        End Sub
        Public Sub RaiseSomeEvent()
            If m_SomeEvent IsNot Nothing Then m_SomeEvent.Invoke()
        End Sub
    End Class
End Namespace
En de client :
Visual Basic 2010 Broncode
Namespace UsingEvents
    Class Client
        Private Shared WithEvents m_SomeFirstEventSource As SomeEventSource
        Public Shared Sub Main()
            m_SomeFirstEventSource = New SomeEventSource
            m_SomeFirstEventSource.RaiseSomeEvent() ' "someEventHandler"
            '
            Dim someSecondEventSource As SomeEventSource = New SomeEventSource
            someSecondEventSource.RaiseSomeEvent() ' /
            AddHandler someSecondEventSource.SomeEvent, _
                       AddressOf someEventHandler
            someSecondEventSource.RaiseSomeEvent() ' "someEventHandler"
            AddHandler someSecondEventSource.SomeEvent, _
                       AddressOf someEventHandler
            someSecondEventSource.RaiseSomeEvent() ' "someEventHandler"
            '                                        "someEventHandler"
            RemoveHandler someSecondEventSource.SomeEvent, _
                          AddressOf someEventHandler
            someSecondEventSource.RaiseSomeEvent() ' "someEventHandler"
            RemoveHandler someSecondEventSource.SomeEvent, _
                          AddressOf someEventHandler
            someSecondEventSource.RaiseSomeEvent() ' /
            '
            Console.ReadLine()
        End Sub
        Private Shared Sub someEventHandler() _
                                        Handles m_SomeFirstEventSource.SomeEvent
            Console.WriteLine("someEventHandler")
        End Sub
    End Class
End Namespace
Console Application Output
someEventHandler
someEventHandler
someEventHandler
someEventHandler
someEventHandler
Omgezet naar :
Visual Basic 2010 Broncode
Namespace UsingDelegates
    Class Client
        Private Shared m_SomeFirstEventSource As SomeEventSource
        Public Shared Property SomeFirstEventSource() As SomeEventSource
            Get
                SomeFirstEventSource = m_SomeFirstEventSource
            End Get
            Set(ByVal value As SomeEventSource)
                If m_SomeFirstEventSource IsNot Nothing Then
                    m_SomeFirstEventSource.remove_SomeEvent(AddressOf _
                                                               someEventHandler)
                End If
                m_SomeFirstEventSource = value
                If m_SomeFirstEventSource IsNot Nothing Then
                    m_SomeFirstEventSource.add_SomeEvent(AddressOf _
                                                               someEventHandler)
                End If
            End Set
        End Property
        Public Shared Sub Main()
            SomeFirstEventSource = New SomeEventSource
            SomeFirstEventSource.RaiseSomeEvent() ' "someEventHandler"
            '
            Dim someSecondEventSource As SomeEventSource = New SomeEventSource
            someSecondEventSource.RaiseSomeEvent() ' /
            someSecondEventSource.add_SomeEvent(AddressOf someEventHandler)
            someSecondEventSource.RaiseSomeEvent() ' "someEventHandler"
            someSecondEventSource.add_SomeEvent(AddressOf someEventHandler)
            someSecondEventSource.RaiseSomeEvent() ' "someEventHandler"
            '                                        "someEventHandler"
            someSecondEventSource.remove_SomeEvent(AddressOf someEventHandler)
            someSecondEventSource.RaiseSomeEvent() ' "someEventHandler"
            someSecondEventSource.remove_SomeEvent(AddressOf someEventHandler)
            someSecondEventSource.RaiseSomeEvent() ' /
            '
            Console.ReadLine()
        End Sub
        Private Shared Sub someEventHandler()
            Console.WriteLine("someEventHandler")
        End Sub
    End Class
End Namespace
Console Application Output
someEventHandler
someEventHandler
someEventHandler
someEventHandler
someEventHandler
Deze omzetting ( die op de achtergrond gebeurt bij het gebruik van de verkorte versie ) verklaart veel, zo wordt verklaard dat :

- Enkel het object waarnaartoe het WithEvents gedeclareerde veld verwijst een eventsource object is.  In de setter van de SomeFirstEventSource property wordt immers eerst de eventhandler losgekoppeld van het oude eventsource object.
- Het gebruik van de RemoveHandler slechts de laatste koppeling met een eventhandler verwijdert, en niet allemaal.  De System.Delegate.Remove zal immers slecht de laatste delegate ( van tweede argument ) niet opnemen in de terugkeer waarde.
- ...

Dit artikel is gepubliceerd op zondag 31 juli 2011 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.