Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No error when Delegate signature doesn't match

I have the following class and delegate defined in code (many other lines snipped out for brevity).

Public Delegate Sub TimerCallback(canceled As Boolean)

Public Class Timer
    Implements TimerManager.ITimer

    Public Sub New(delay As Integer, callback As TimerCallback)
        mState = TimerState.Setup
        mCallback = callback
        CType(TimerManager.Instance, TimerManager.ITimerManager).RegisterTimer(Me, delay)
    End Sub
End Class

When I create a new instance of the timer with the following code, I do NOT get a compile error, even though the signature of the anonymous function does not match the signature of the delegate (it's missing the "canceled as boolean" param).

 Dim timer As New Timer(Me.CookTime, Sub()
                                         Dim cooked As FoodBase = CType(Activator.CreateInstance(SuccessfulResult), FoodBase)
                                         player.GetBackpack.AddItem(cooked)
                                     End Sub)

I expect to get a compile error when instantiating the timer this way, can anyone explain why It is compiling without an error? Are there any options I can set that will cause it to produce a compile error? I have option explicit on, option strict on, and option infer off in the project properties. As it is, it is way too easy to forgot to include the canceled argument.

like image 901
Bradley Uffner Avatar asked Nov 23 '12 21:11

Bradley Uffner


2 Answers

Yep. That's fine - the compiler can generate an anonymous method knowing the signature that is needed, and simply not use the parameters it is given. So the compiler-generated method will have the parameter - it just won't use it. You can do the same in C# using delegate { ... }.

like image 67
Marc Gravell Avatar answered Nov 02 '22 18:11

Marc Gravell


This phenomenon is called Relaxed Delegate Conversion, and has slightly different behavior when Option Strict is on and off. Please follow the link for more details.

It is a feature of VB, which allows for compact code, such as this:

Private Sub Form1_Load() Handles MyBase.Load

If you are not using any of the arguments, why declare them all? I personally see it as a benefit of VB, rather than a problem. If you attempt to do the same in C#, you get a compile error like this:

No overload for 'Form1_Load' matches delegate 'System.EventHandler'.

like image 36
Neolisk Avatar answered Nov 02 '22 17:11

Neolisk