Please take a look at the code below, which works as I would expect:
Partial Class _Default
Inherits System.Web.UI.Page
Delegate Sub TestEventHandler(ByVal o As Object, ByVal e As EventArgs)
Dim alhandler As TestEventHandler = AddressOf TestEventMethod
Public Event Test1 As TestEventHandler
Public Event Test2 As TestEventHandler
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
AddHandler Me.Test1, alhandler
AddHandler Me.Test2, alhandler
RaiseEvent Test1(Me, e)
RaiseEvent Test2(Me, e)
RemoveHandler Me.Test1, alhandler
RaiseEvent Test1(Me, e)
End Sub
Public Sub TestEventMethod(ByVal o As Object, ByVal e As EventArgs)
MsgBox("Test")
End Sub
End Class
I am confused with the two statements below:
Dim alhandler As TestEventHandler = AddressOf TestEventMethod '1
Public Event Test1 As TestEventHandler '2
1) This is saying that the reference of alHandler is a delegate that points to the address of a function. 2) This is saying that Test1 is an event of type Delegate. How can an event and a handler be a delegate?
As others have said, each type of delegate is a type, just as if it were a regular class. So, in your example code,
TestEventHandler
is a delegate type. ATestEventHandler
variable can reference anyTestEventHandler
object, just like any other variable can reference any object of its own type.TestEventHandler
objects must be instantiated, just like objects of any other type.Delegates are special, however, in that you declare them using a different, special, syntax. For instance, if you had the following method:
You could create a delegate that matches that method signature like this:
Remember, by doing so, that simply defines the
MyMethodDelegate
type. That doesn't declare a variable of that type nor does it instantiate an object of that type.There are two things in VB.NET syntax, however, which often cause a lot of confusion. First, when you declare an event, you can use two different syntax:
Both of those lines do the same thing. The first line defines the event using an already defined delegate type. The second line essentially defines a new unnamed delegate on the fly and then uses it as the type for the event. (Note, I'm using the
MyMethodDelegate
for simplicity, and that will work, but standards dictate that events should have a sender and an event args.) When an event is declared, think of it like a variable. Behind the scenes, it's really like a collection object that keeps a list of all the delegate objects that are added to it using theAddHandler
function.The second confusing thing in VB.NET is that the compiler will automatically instantiate a new delegate object for you, if necessary, when you use the
AddressOf
function. So, for instance, when you do something like this:It's just a shortcut for typing the full text, like this:
The latter, in my opinion is much more clear. What you are actually doing is creating a new object of that delegate type and pointing that delegate object to that method, and then adding that delegate object to the event (that event collection-like variable defined by the object's type).
So, in your example, this line:
Would be more clearly written as:
It's declaring a delegate variable and then setting it to a new delegate object that points to that particular method. In this case, it's just a standard delegate variable, not an event. Events are very similar to delegates field/properties. Events are essentially an accessor wrapper around a private delegate field, in the same way that properties often wrap a private field. The big differences between delegate fields and events are that events support the
AddHandler
andEventHandler
functions and events cannot be raised/invoked from outside of the class that defines it.