2010-03-17 9 views
81

que actualmente tienen una página de la que se declara como sigue:Uso de expresiones lambda para controladores de eventos

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

me he mudado recientemente a .NET 3.5 de 1.1, así que estoy acostumbrado a escribir controladores de eventos fuera de Page_Load. Mi pregunta es; ¿Hay algún inconveniente o desventaja en el rendimiento que deba tener en cuenta cuando uso el método lambda para esto? Lo prefiero, ya que es ciertamente más conciso, pero no quiero sacrificar el rendimiento para usarlo. Gracias.

Respuesta

81

No hay implicaciones de rendimiento ya que el compilador traducirá su expresión lambda en un delegado equivalente. Las expresiones Lambda no son más que una función de lenguaje que el compilador traduce en el mismo código exacto con el que está acostumbrado a trabajar.

El compilador convierte el código que tiene que algo como esto:

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

I see. Entonces, ¿no hay desventaja de tener estos controladores dentro de Page_Load versus tenerlos fuera de él? –

+1

La convención que prevalece es adjuntar manejadores de eventos en el método 'OnInit' pero dado que el evento' Click' de un botón se levantará después de que la página cargue este ejemplo está bien. –

+6

Es importante tener en cuenta que sin retener una referencia al delegado, no puede darse de baja del evento. – snarf

2

No hay implicaciones de rendimiento que yo sepa o alguna vez ha topado, por lo que yo sé que es sólo "azúcar sintáctico" y compila hasta lo mismo que usando la sintaxis de delegado, etc.

42

En cuanto al rendimiento, es lo mismo que un método con nombre. El gran problema es cuando hace lo siguiente:

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

Probablemente se trate de quitar una lambda diferente, dejando el original allí. Entonces, la lección es que está bien a menos que también quieras poder eliminar el controlador.

+2

"Probablemente * intente ..."? ¿Eliminará * alguna vez * el controlador correcto en una situación así? –

+1

@ O.R.Mapper: si el lambda captura una variable, no puede eliminar el controlador correcto. En otras circunstancias, depende del compilador. – Gabe

+0

¿De verdad? Interesante - entonces, si registro dos funciones anónimas que parecen iguales (wlog tiene un cuerpo vacío), y luego anulo el registro (usando '- =') otra función anónima que también tiene un cuerpo vacío, esencialmente no está definido cuál de las Se eliminarán dos controladores de eventos o si se eliminará alguno de ellos. –

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

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

Información muy útil, aunque está fuera de tema (la pregunta es sobre el rendimiento). –

+2

No exactamente fuera del tema, ya que el uso de la memoria puede llevar a una degradación del rendimiento. – Vladius

+1

Quitarse él mismo en un manejador también puede ser útil: '' 'C# EventHandler handler = null; handler = (s, e) => {MessageBox.Show ("Woho"); button.Click - = controlador;} '' ' – Vladius

Cuestiones relacionadas