Cierre capturado (variable de bucle) en C # 5.0

Esto funciona bien (significa como se esperaba) en C # 5.0:

var actions = new List(); foreach (var i in Enumerable.Range(0, 10)) { actions.Add(() => Console.WriteLine(i)); } foreach (var act in actions) act(); 

Imprime del 0 al 9. Pero este muestra 10 por 10 veces:

 var actions = new List(); for (var i = 0; i  Console.WriteLine(i)); } foreach (var act in actions) act(); 

Pregunta: Este era un problema que teníamos en las versiones de C # anteriores a 5.0; así que tuvimos que usar un marcador de posición local de bucle para el cierre y ahora se lo arregla, en C # 5.0, en los bucles “foreach”. ¡Pero no en “para” bucles!

¿Cuál es el razonamiento detrás de esto (no resuelve el problema for bucles for )?

¿Cuál es el razonamiento detrás de esto?

Voy a suponer que quieres decir “¿por qué no ha cambiado for bucles también?”

La respuesta es que para bucles for , el comportamiento existente tiene perfecto sentido. Si rompes un bucle for en:

  • inicializador
  • condición
  • iterador
  • cuerpo

… entonces el ciclo es aproximadamente:

 { initializer; while (condition) { body; iterator; } } 

(Excepto que el iterator se ejecuta al final de una instrucción continue; también, por supuesto).

La parte de inicialización lógicamente solo ocurre una vez, por lo que es completamente lógico que solo haya una “instanciación variable”. Además, no existe un valor “inicial” natural de la variable en cada iteración del ciclo. No hay nada que decir que un ciclo for debe ser de un formulario que declare una variable en el inicializador, lo pruebe en la condición y lo modifique en el ciclo. iterador. ¿Qué esperarías que hiciera un ciclo como este?

 for (int i = 0, j = 10; i < j; i++) { if (someCondition) { j++; } actions.Add(() => Console.WriteLine(i, j)); } 

Compare eso con un bucle foreach que parece que está declarando una variable separada para cada iteración. Diablos, la variable es de solo lectura, lo que hace aún más extraño pensar que es una variable que cambia entre iteraciones. Tiene mucho sentido pensar que un bucle foreach declare una nueva variable de solo lectura en cada iteración con su valor tomado del iterador.