5

我在代码中定义了以下类和委托(为简洁起见,剪掉了许多其他行)。

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

当我使用以下代码创建计时器的新实例时,即使匿名函数的签名与委托的签名不匹配(它缺少“取消为布尔值”参数),我也不会收到编译错误。

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

我希望以这种方式实例化计时器时会出现编译错误,谁能解释为什么它正在编译而没有错误?有没有我可以设置的选项会导致它产生编译错误?我在项目属性中有选项显式打开、选项严格打开和选项推断关闭。事实上,忘记包含取消的参数太容易了。

4

2 回答 2

4

是的。这很好 - 编译器可以生成一个知道所需签名的匿名方法,而根本不使用它给出的参数。因此编译器生成的方法将具有参数 - 它只是不会使用它。您可以在 C# 中使用delegate { ... }.

于 2012-11-23T21:30:33.007 回答
3

这种现象称为Relaxed Delegate Conversionon ,当 Option Strict 为和时,其行为略有不同off。请点击链接了解更多详情。

它是 VB 的一个特性,它允许紧凑的代码,例如:

Private Sub Form1_Load() Handles MyBase.Load

如果您不使用任何参数,为什么要全部声明它们?我个人认为这是 VB 的好处,而不是问题。如果您尝试在 C# 中执行相同操作,则会收到如下编译错误:

“Form1_Load”没有重载匹配委托“System.EventHandler”。

于 2012-11-23T22:01:56.097 回答