Relaxed delegates, how?

The basic concept of delegates is this: Like a class, you can create instances from a delegate. An instance of a class can represent anything, but an instance of a delegate can only represent a method. A class has a body, a delegate does not need one. Instead, you provide a reference to a function to the delegate constructor. This form calls a method called MySub in the Load event handler:

Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.MySub(10)
End Sub

Private Sub MySub(ByVal X As Integer)
MessageBox.Show((X * 2).ToString())
End Sub

End Class

If I declare a delegate (the last line), in this case MyDelegate, I could make an instance of the delegate, pass a reference to MySub to the constructor, and then use the delegate to call MySub. Now I have the possibility to pass the delegate around, so that the method can be called by code outside the object, even thou the sub is private. This is used for event handling in Visual Basic.

Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim X As New MyDelegate(AddressOf MySub)
X(10)
End Sub

Private Sub MySub(ByVal X As Integer)
MessageBox.Show((X * 2).ToString())
End Sub

End Class

Public Delegate Sub MyDelegate(ByVal X As Integer)

Notice how the signature of MySub must match the signature of MyDelegate. If it doesn’t, instances of MyDelegate can’t reference MySub.

Now, let’s say that I add a button to the Form. I want to bind a method to the Click event of that Button (Button1). This what I would have to do to dynamically bind the method: Create the method with the correct signature, user the AddHandler command to bind the method to the Click event of the button. Here is the code for doing that:

Public Class Form1

‘The method…
Private Sub Buttonclick(ByVal sender As System.Object, ByVal e As System.EventArgs)
MessageBox.Show(“Hello”)
End Sub

‘…and the binding.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim H As New EventHandler(AddressOf Buttonclick)
AddHandler Button1.Click, H
End Sub

End Class

I must know the signature that is expected, to be able to bind Buttonclick to the Click event of the Button. That is fair, but what if I don’t need the arguments? Just modifying the signature of Buttonclick will not compile, but I can use relaxed delegates here. Despite the things I have read about relaxed delegates, I can not use them on dynamically bound event handlers. This would work in both Visual Basic 8 and 9:

Public Class Form1

‘The method with declarative binding
Private Sub Buttonclick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MessageBox.Show(“Hello”)
End Sub

End Class

In Visual Basic 9, the Buttonclick method can have a different signature. This will work just as good, and here relaxed delegates are used:

Public Class Form1

‘The method with declarative binding – relaxed!
Private Sub Buttonclick() Handles Button1.Click
MessageBox.Show(“Hello”)
End Sub

End Class

The arguments (sender and e) is no longer available to me, but if I don’t need them that is not a problem. If I want to use arguments, the number of arguments in my handler must be the same, and the type of each argument must be the same or less specific.