Visual Basic generally goes out of its way to help out the programmer. Delegate relaxation is a good example of this need to please. Simply put, this feature is about being able to assign to delegates when the signatures don’t exactly match. The canonical example goes like this:
Sub ClickHandler() Handles Button1.Click
Button1.Click takes two parameters whereas ClickHandler takes no parameters. This is quite a convenience if you don’t plan to use the eventargs.
Another example that’s easier to examine is something like:
Dim a As Action = AddressOf String.Empty.ToString
Action is a delegate that takes no parameters and has no return type. We are assigning a function to it which has a return type of String. Here is the code that’s generated for this case.
Dim $VB$Closure_ClosureVariable_14_D As New _Closure$__1 $VB$Closure_ClosureVariable_14_D.$VB$Local_VB$t_string$S1 = String.Empty Dim a As Action = New Action(AddressOf $VB$Closure_ClosureVariable_14_D._Lambda$__1) Public Sub _Lambda$__1() Me.$VB$Local_VB$t_string$S1.ToString End Sub
What is all this messy code doing? What happens is that when the compiler sees a delegate of type <expr>.method it breaks it down into temp = <expr> and temp.Method. The temp var is then hoisted into a closure if needed. The closure class also has a method which has the right signature needed for the target delegate. This function simply calls temp.Method. If there was no relaxation needed (meaning no lambda is generated) then the temp is simply a temp and doesn’t have to be hoisted.