Mi sono appena imbattuto in una situazione in cui un collega ha scritto un bug e non abbiamo capito perché è successo nonostante il fatto che sappiamo come risolverlo. Uso le espressioni lamda da anni ma ho molta più esperienza con C# rispetto a VB e ovviamente ho un fondamentale fraintendimento di qualcosa.Bug causato dall'uso della funzione invece della sub linea singola espressione lambda
Quanto segue si osserva in Visual Studio 2010 con .Net 3.5.
Ho semplificato questo giù al seguente codice semplice test che riproduce uno scenario simile:
Su un Windows Form ho messo il seguente, per eseguire semplicemente un lambda e quindi stampare il valore di un oggetto di prova per una casella di testo:
Private Sub ExecuteAction(ByVal action As Action(Of TestClass))
Dim testObj As New TestClass()
action(testObj)
TextBox1.Text = testObj.MyInteger
End Sub
Public Class TestClass
Public MyInteger As Integer
End Class
e quindi eseguo un codice per chiamarlo utilizzando un lambda.
Nel seguente caso l'uscita nella casella di testo è di 15 come mi sarei aspettato:
ExecuteAction(Sub(obj) obj.MyInteger = 15)
Nel seguente caso l'uscita è anche 15 come ci si aspetta (lo fa generare un avviso perché nessun valore di ritorno è specificato che capisco e va bene perché fa quello che ci si aspetta):
ExecuteAction(Function(obj)
obj.MyInteger = 15
End Function)
Nel seguente caso l'uscita è 0 e non capisco il motivo per cui:
ExecuteAction(Function(obj) obj.MyInteger = 15)
Perché nello scenario finale il valore dell'oggetto non cambia in 15? Ho bisogno di capire questa differenza tra lambdas funzione singola linea e lambda funzione multi linea per vedere se ho bisogno di controllare attraverso tutti i nostri prodotti per bug simili. Compila bene e non genera avvisi che lo rendono estremamente pericoloso per i nostri usi.
Ho provato quanto segue per vedere se facesse differenza costringendo l'esecuzione prima di qualsiasi ritorno implicito ma no:
ExecuteAction(Function(obj) (obj.MyInteger = 15))
grazie, ha senso. Ovviamente la situazione diretta non può accadere in C# perché ha == per il confronto e = per l'incarico che mi ha confuso. Mi assicurerò che i nostri standard di programmazione siano aggiornati e facciano una valutazione per verificare quanto è probabile che questo ci abbia catturato altrove. Grazie ancora. –