1

I'm asking specifically about VB.NET, but I imagine the general principles are the same in other languages. I thought an event was a first-class concept in .NET, but it seems from reflection that its just a specific method which is called when the event is raised.

  1. How do AddHandler and RemoveHandler modify the method dynamically (AFAIK, events pre-date DynamicMethods?
  2. How does RaiseEvent call the method?
  3. Why are AddHandler, RemoveHandler, and RaiseEvent implemented as statements instead of methods?
Community
  • 1
  • 1
just.another.programmer
  • 8,579
  • 8
  • 51
  • 90

2 Answers2

2

No, an event is just a combination of two or three methods (the "raise" part is optional) in the same way that a property is a combination of one or two methods.

AddHandler and RemoveHandler don't modify methods at all. They just call the "add" and "remove" parts of the event, which are resposible for the implementation part.

Typically an event is implemented via a reference to a field with the appropriate delegate type, with Delegate.Combine and Delegate.Remove used to perform the appropriate operations. (The field value will be changed - bear in mind that delegate types are immutable.) Raising an event just consists of invoking the delegate.

As for why AddHandler etc are separate statement types - if they were methods, what would the parameters be? Something has to refer to "the event". Basically an AddHandler statement corresponds to the appropriate event "add" method, just as a property fetch corresponds to the appropriate property "get" method. You can do this with reflection, via EventInfo.AddHandler.

See my article on delegates and events for more details which may help - it's from a C# background, but the principles are obviously the same.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Does that mean `RaiseEvent SomeEvent` and `SomeEvent()` have the same affect (where `SomeEvent` is declared as `Public Event SomeEvent As Action`). Using the `SomeEvent()` syntax in VS2010 gives me a compile error that I must use the `RaiseEvent` syntax. – just.another.programmer Apr 29 '13 at 14:52
  • @just.another.programmer: Well I believe they would have the same effect if you *could* just get at the value, yes :) But that's a detail of the VB side of things, which I'm not as familiar with. – Jon Skeet Apr 29 '13 at 14:54
1

An event is just a delegate. Here's some code to play with that works just like a regular event, using a delegate object instead:

Module Module1
    Sub Main()
        Dim obj As New Example
        obj.AnEvent = New EventHandler(AddressOf Handler)
        obj.Test()
        Console.ReadLine()
    End Sub

    Sub Handler(ByVal sender As Object, ByVal e As EventArgs)
        Console.WriteLine("got event")
    End Sub
End Module

Class Example
    Public AnEvent As EventHandler
    Public Sub Test()
        If AnEvent IsNot Nothing Then AnEvent(Me, EventArgs.Empty)
    End Sub
End Class

But do note the problem with this code. Some other code could mess with AnEvent as well. Like replacing it or setting it back to Nothing. That's disastrous in most any case, the code that subscribed the event first will stop working properly.

The Event keyword in VB.NET prevents this from happening. It wraps the delegate object and makes it inaccessible to other code, beyond the provided keywords. Somewhat similar to how a Property protects access to a field. AddHandler and RemoveHandler ensure that existing registrations cannot disappear. RaiseEvent fires the event without the need for the Nothing check.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536