2010-03-17 18 views
81

Io attualmente avere una pagina che viene dichiarato come segue:Uso delle espressioni lambda per i gestori di eventi

public partial class MyPage : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     //snip 
     MyButton.Click += (o, i) => 
     { 
      //snip 
     } 
    } 
} 

ho solo di recente trasferito a .NET 3.5 da 1.1, quindi sono abituato a scrivere i gestori di eventi al di fuori del Page_Load. La mia domanda è; Ci sono degli inconvenienti o delle insidie ​​nelle prestazioni che dovrei fare attenzione quando uso il metodo lambda per questo? Lo preferisco, in quanto è certamente più conciso, ma non voglio sacrificare le prestazioni per usarlo. Grazie.

risposta

81

Non ci sono implicazioni sulle prestazioni dal momento che il compilatore tradurrà la tua espressione lambda in un delegato equivalente. Le espressioni Lambda non sono altro che una funzione linguistica che il compilatore traduce nello stesso identico codice con cui sei abituato a lavorare.

Il compilatore converte il codice è necessario qualcosa di simile:

public partial class MyPage : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     //snip 
     MyButton.Click += new EventHandler(delegate (Object o, EventArgs a) 
     { 
      //snip 
     }); 
    } 
} 
+0

Vedo. Quindi non c'è anche nessun inconveniente dall'avere questi gestori all'interno di Page_Load contro averli al di fuori di esso? –

+1

La convenzione prevalente è quella di associare i gestori di eventi nel metodo 'OnInit', ma poiché l'evento' Click' di un pulsante verrà generato dopo che la pagina caricherà questo esempio va bene. –

+6

Importante notare che senza conservare un riferimento al delegato, non è possibile annullare l'iscrizione all'evento. – snarf

2

Nessuna incidenza delle prestazioni che io sappia o abbia mai incontrato, per quanto ne so il suo solo "zucchero sintattico" e si riduce alla stessa cosa dell'uso della sintassi dei delegati, ecc.

42

Per quanto riguarda le prestazioni, corrisponde a un metodo denominato. Il grosso problema è quando si effettuano le seguenti operazioni:

MyButton.Click -= (o, i) => 
{ 
    //snip 
} 

Sarà probabilmente cercare di rimuovere un lambda diversa, lasciando quella originale lì. Quindi la lezione è che va bene a meno che tu non voglia anche essere in grado di rimuovere il gestore.

+2

"Probabilmente * cercherà di ..."? * Rimuoverà * mai il gestore corretto in una situazione del genere? –

+1

@ O.R.Mapper: se lambda cattura una variabile, non può rimuovere il gestore corretto. In altre circostanze, dipende dal compilatore. – Gabe

+0

Davvero? Interessante - quindi, se registro due funzioni anonime che sembrano uguali (il wlog ha un corpo vuoto), e poi annullo (usando '- =') un'altra funzione anonima che ha anch'essa un corpo vuoto, è essenzialmente indefinito quale dei verranno rimossi due gestori di eventi o se qualcuno di essi verrà rimosso? –

28
EventHandler handler = (s, e) => MessageBox.Show("Woho"); 

button.Click += handler; 
button.Click -= handler; 
+1

Informazioni molto utili, anche se sono fuori tema (la domanda riguarda le prestazioni). –

+2

Non esattamente fuori tema poiché l'utilizzo della memoria può comportare un downgrade delle prestazioni. – Vladius

+1

Anche la rimozione stessa di un handler può essere utile: '' 'C# EventHandler handler = null; handler = (s, e) => {MessageBox.Show ("Woho"); button.Click - = gestore;} '' ' – Vladius

Problemi correlati