2010-07-14 9 views
11

Después de descubrir las expresiones lambda, y su uso como funciones anónimas, he encontrado a mí mismo escribiendo un montón de acontecimientos más triviales como éstas:mejores prácticas de la utilización de expresiones lambda para controladores de eventos

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

tengo también alejado de los controladores de eventos que acaba de llamar a otras funciones, reemplazándolos con pequeñas lambdas, que hacen lo mismo:

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

que he encontrado algunas preguntas similares abordar performance concerns y señalando que can't remove them, pero no tienen encontrado cualquier abordar la simple pregunta de ¿es esta una buena idea?

¿El uso de lambdas se considera de buena forma, o los programadores tienen más experiencia en esto? ¿Oculta los manejadores de eventos en lugares difíciles de encontrar o hace que el código sea un servicio al reducir el número de manejadores de eventos triviales?

Respuesta

15

Es una idea perfectamente razonable - pero en este caso particular, me gustaría utilizar un método anónimo en su lugar:

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

El beneficio es que usted no tiene que especificar los parámetros - que hace que sea más claro que no los estás usando Esta es la única ventaja de que los métodos anónimos tienen sobre las expresiones lambda.

El golpe de rendimiento casi siempre será insignificante. La imposibilidad de eliminarlos después es un problema muy real si do necesita ser capaz de eliminar el controlador, pero me parece que a menudo no lo hago. (Reactive Extensions tiene un buen enfoque para esto: cuando te suscribes a una secuencia observable, te devuelven un IDisposable que eliminará la suscripción si lo llamas. Muy limpio.)

1

En realidad, lo consideras un evento manejadores en lugares fáciles de encontrar, a saber, justo al lado del nombre del evento al que está asignado.

Una gran parte del tiempo, verá los controladores de eventos como:

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

adjunta al evento KeyUp txtFirstName, porque después de usar IntelliSense para crear el manejador, alguien decidió cambiar el nombre del cuadro de texto y que KeyUp funcionó mejor. Con el Lambda, el objeto, el evento y la función están todos juntos.

0

Es complicado. Recuerdo haber leído en Code Complete cómo algunas personas (inteligentes) dicen que debes mantener el flujo de control lo más simple posible, y muchos argumentan a favor de los puntos de entrada y salida únicos de un método, porque no hacerlo dificultaba el seguimiento del programa.

Lambdas se están alejando aún más de eso, lo que hace que en algunos casos sea muy difícil seguir lo que está sucediendo, con control saltando de un lugar a otro.

Básicamente, creo que probablemente sea una mala idea debido a esto, pero también es potente y hace la vida más fácil. Ciertamente los uso bastante. En resumen, ¡use con precaución!

+6

Restringirse a un único punto de salida es una receta para los desastres de legibilidad, IMO. Si conozco el resultado de un método después de una línea (p.porque es un caso especial), entonces no hay razón para que el lector siga el resto del método para llegar al punto de salida. –

+0

Estoy de acuerdo, siempre me gustaría una salida anticipada. Pero sé que algunas personas se oponen a esto. –

+0

Mi filosofía es que a menudo es deseable evitar que las funciones salgan entre la primera declaración que tiene efectos secundarios y la última declaración, excepto que devolver un valor desde un bloque 'try' puede ser más limpio que establecer una variable dentro del bloquear y devolverlo desde afuera. – supercat