Advertencia: Mi respuesta en realidad describe las variables capturadas, que es diferente de la elevación lambda. Lea mal la pregunta (necesita dormir). Pero dediqué un poco de tiempo a escribir esto, así que no me gusta borrarlo. Lo dejé como una comunidad WIKI.
El levantamiento lambda, a menudo referido como cierres, es una forma de permitir el acceso de variables de ámbito dentro de una expresión lambda anidada.
Es difícil entrar en los detalles esenciales de los cierres sin elegir un idioma en particular. Uno de los efectos secundarios del levantamiento de lambda, en cualquier lengua, es que tiende a extender la vida útil de una variable desde un ámbito local de corta duración a un alcance mucho más prolongado. Por lo general, esto ocurre en forma de transferir una variable de la pila al montón dentro del compilador. Esta es una acción muy específica del lenguaje y por lo tanto produce implementaciones muy diferentes basadas en el lenguaje.
Me centraré en C# ya que ese es probablemente el lenguaje más común para los lectores de desbordamiento de pila. Comencemos con el siguiente código.
public Func<int> GetAFunction() {
var x = 42;
Func<int> lambda1 =() => x;
Func<int> lambda2 =() => 42;
...
return lambda1;
}
En este ejemplo, hemos creado 2 expresiones lambda. En ambos casos, se asigna a una instancia de delegado de tipo Func. Todos los delegados en .Net requieren que una función real los respalde en alguna parte. Entonces, bajo el capó, todas las expresiones lambda/funciones anónimas en C# se traducen en una definición de método.
Generar una función para lambda2 es bastante sencillo. Es una función aislada que simplemente devuelve un valor constante.
public static int RealLambda2() {
return 42;
}
Generar lambda1 es bastante más difícil. Una definición literal sería tener el siguiente
public static int RealLambda1() {
return x;
}
Esto, obviamente, no se compilará porque x no es accesible. Para que esto funcione, el compilador C# debe levantar la variable x en un cierre. A continuación, puede devolver un puntero a una función dentro del cierre para satisfacer la expresión delegado
class Closure1 {
int x;
public int RealLambda1() {
return x;
}
}
Este es un ejemplo bastante simple, pero todo funciona correctamente detalle el arte de la elevación. El diablo lamentablemente está en los detalles y se vuelve mucho más complejo con el escenario.
Lea acerca de los cierres primero - http://en.wikipedia.org/wiki/Closure_(computer_science) – dirkgently