2012-11-23 12 views
5

Ho la seguente classe e delegato definita nel codice (molte altre righe eliminate per brevità).Nessun errore quando la firma delega non corrisponde a

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 

Quando creo una nuova istanza del timer con il seguente codice, non ottengo un errore di compilazione, anche se la firma della funzione anonima non corrisponde alla firma del delegato (manca il " annullato come "param" booleano.

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

mi aspetto di ottenere un errore di compilazione quando si crea un'istanza del timer in questo modo, qualcuno può spiegare perché sta compilando, senza un errore? Ci sono opzioni che posso impostare per produrre un errore di compilazione? Ho un'opzione esplicita on, opzione strict on e opzione dedotta nelle proprietà del progetto. Così com'è, è troppo facile dimenticare di includere l'argomento cancellato.

risposta

4

Sì. Va bene - il compilatore può generare un metodo anonimo conoscendo la firma che è necessaria, e semplicemente non utilizzare i parametri che è stato dato. Quindi il metodo generato dal compilatore sarà con il parametro - lo non lo userà semplicemente. Puoi fare lo stesso in C# usando delegate { ... }.

+1

Non è il punto di digitare con forza l'argomento su TimerCallback per garantire che la firma del metodo corrisponda? Potrei vedere questo comportamento se Option Infer fosse impostato su On. Ma impostando Option Infer Off mi aspetto che il compilatore non deduca nulla e imponga la firma. Avete qualche soluzione alla seconda parte della mia domanda su come forzare la compilazione a generare un errore o almeno un avvertimento in questa situazione? –

3

Questo fenomeno è chiamato Relaxed Delegate Conversion e ha un comportamento leggermente diverso quando Option Strict è on e off. Si prega di seguire il link per maggiori dettagli.

Si tratta di una caratteristica di VB, che permette di codice compatto, come questo:

Private Sub Form1_Load() Handles MyBase.Load 

Se non si utilizza uno qualsiasi degli argomenti, per cui tutti dichiarare? Personalmente lo vedo come un vantaggio di VB, piuttosto che un problema. Se si tenta di fare lo stesso in C#, si ottiene un errore di compilazione come questo:

Nessun sovraccarico per 'Form1_Load' partite delegato 'System.EventHandler'.

+0

L'argomento non viene utilizzato in/this/example, ma può essere utilizzato in altri posti. Il mio codice di timer fa parte di una libreria che altre persone possono utilizzare nei loro progetti. Se questi utenti non sono a conoscenza della firma per TimerCallback, potrebbero trascurare di includerlo o persino conoscere la possibilità di annullare i timer. –

+1

@BradleyUffner: VB offre la flessibilità di dichiararlo con parametro solo dove ha bisogno del parametro. È inoltre possibile gestire più eventi con diverse firme in un sottosistema in questo modo, ad esempio per scopi di registrazione o di debug. Gli utenti dovrebbero leggere la documentazione prima di utilizzare il prodotto. Successivamente è la loro scelta se specificare sempre la firma completa o abbreviare se necessario. Vedi la mia modifica per maggiori informazioni. – Neolisk

+0

Grazie per le informazioni aggiunte e il nome formale effettivo di questa funzione. –

Problemi correlati