2010-07-14 8 views
11

Dopo aver scoperto le espressioni lambda, e il loro uso come funzioni anonime, mi sono trovato a scrivere un sacco di eventi più banali come questi:Le migliori pratiche di utilizzo di espressioni lambda per i gestori di eventi

txtLogin.GotFocus += (o, e) => 
{ 
    txtLogin.Text = string.Empty; 
    txtLogin.ForeColor = SystemColors.ControlText; 
}; 
txtLogin.LostFocus += (o, e) => 
{ 
    txtLogin.Text = "Login..."; 
    txtLogin.ForeColor = SystemColors.InactiveCaptionText; 
}; 

ho anche allontanato da gestori di eventi che ha appena chiamata altre funzioni, la loro sostituzione con piccole lambda, che fanno la stessa:

backgroundWorker.DoWork += (o, e) => DatabaseLookup.Open(e.Argument as string); 

ho trovato alcune domande simili affrontare performance concerns e sottolineando che si can't remove them, ma non ho trovato qualsiasi affrontare la semplice domanda di è una buona idea?

L'uso di lambda è considerato una buona forma oppure i programmatori di più esperienza non lo considerano? Nasconde i gestori di eventi in luoghi difficili da trovare, oppure esegue il codice di un servizio riducendo il numero di gestori di eventi banali?

risposta

15

È un'idea perfettamente ragionevole - ma in questo caso particolare, vorrei usare un metodo anonimo invece:

txtLogin.LostFocus += delegate 
{ 
    txtLogin.Text = "Login..."; 
    txtLogin.ForeColor = SystemColors.InactiveCaptionText; 
}; 

Il vantaggio è che non c'è bisogno di specificare i parametri - che lo rende più chiaro che non li stai usando. Questo è il solo vantaggio che i metodi anonimi hanno su espressioni lambda.

Il risultato della prestazione è quasi sempre trascurabile. L'impossibilità di rimuoverli in seguito è un problema molto reale se si desidera che lodo rimuova il gestore, ma spesso non lo trovo. (Reactive Extensions ha un buon approccio a questo - quando ti iscrivi a una sequenza osservabile, ti viene restituito uno IDisposable che rimuoverà l'abbonamento se lo chiami. Molto pulito.)

1

In realtà, si consideri mettendo l'evento gestori in luoghi facili da trovare, ovvero proprio accanto al nome dell'evento a cui è assegnato.

Un sacco di tempo, vedrete i gestori di eventi come:

void Text1_KeyDown(....) {....} 

collegato all'evento KeyUp di txtFirstName, perché dopo aver usato Intellisense per creare il gestore, qualcuno ha deciso di rinominare la casella di testo, e KeyUp ha funzionato meglio. Con Lambda, l'oggetto, l'evento e la funzione sono tutti insieme.

0

È difficile. Ricordo di aver letto in Code Complete come alcune persone (intelligenti) dicono che dovresti mantenere il flusso del controllo il più semplice possibile, con molti che sostengono punti di entrata e uscita singoli da un metodo, perché non farlo rende il programma più difficile da seguire.

Lambdas si sta allontanando ancora di più da questo, rendendo in alcuni casi molto difficile seguire ciò che sta accadendo, con il controllo che salta da un posto all'altro.

Fondamentalmente, penso che probabilmente è una cattiva idea per questo, ma è anche potente e rende la vita più facile. Li uso sicuramente una buona quantità. In sintesi, usare con cautela!

+6

Restringersi a un singolo punto di uscita è una ricetta per i disastri di leggibilità, IMO. Se conosco il risultato di un metodo dopo una riga (ad es.perché è un caso speciale), quindi non c'è motivo di far seguire al lettore il resto del metodo per arrivare al punto di uscita. –

+0

Sono d'accordo, preferirei sempre un'uscita anticipata. Ma so che alcune persone si oppongono a questo. –

+0

La mia filosofia è che spesso è preferibile evitare di uscire dalle funzioni tra la prima istruzione che ha effetti collaterali e l'ultima di tali istruzioni, eccetto che restituire un valore da un blocco 'try' può essere più pulito dell'impostazione di una variabile all'interno del bloccare e restituirlo dall'esterno. – supercat

Problemi correlati