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

この現象はRelaxedDelegateConversiononと呼ばれ、OptionStrictがとの場合の動作がわずかに異なりますoff。詳細については、リンクをたどってください。

これはVBの機能であり、次のようなコンパクトなコードを可能にします。

Private Sub Form1_Load() Handles MyBase.Load

引数を使用していない場合、なぜそれらすべてを宣言するのですか?個人的には、問題ではなく、VBのメリットだと思っています。C#で同じことを行おうとすると、次のようなコンパイルエラーが発生します。

'Form1_Load'のオーバーロードはデリゲート'System.EventHandler'と一致しません。

于 2012-11-23T22:01:56.097 に答える