net vb.net lambda iteration warnings

vb.net - func vb net



¿Por qué es malo usar una variable de iteración en una expresión lambda? (2)

Considera este código:

List<Action> actions = new List<Action>(); for (int i = 0; i < 10; i++) { actions.Add(() => Console.WriteLine(i)); } foreach (Action action in actions) { action(); }

¿Qué esperas que imprima? La respuesta obvia es 0 ... 9 - pero en realidad imprime 10, diez veces. Es porque solo hay una variable que es capturada por todos los delegados. Es este tipo de comportamiento el que es inesperado.

EDITAR: Acabo de ver que estás hablando de VB.NET en lugar de C #. Creo que VB.NET tiene reglas aún más complicadas, debido a la forma en que las variables mantienen sus valores en todas las iteraciones. Esta publicación de Jared Parsons brinda información sobre el tipo de dificultades involucradas, a pesar de que regresó de 2007, por lo que el comportamiento real puede haber cambiado desde entonces.

Estaba escribiendo un código rápido y noté este error de compilación

Usar la variable de iteración en una expresión lambda puede tener resultados inesperados.
En su lugar, cree una variable local dentro del ciclo y asígnele el valor de la variable de iteración.

Sé lo que significa y puedo arreglarlo fácilmente, no es gran cosa.
Pero me preguntaba por qué es una mala idea usar una variable de iteración en un lambda.
¿Qué problemas puedo causar más adelante?


Suponiendo que te refieres a C # aquí.

Es por la forma en que el compilador implementa cierres. El uso de una variable de iteración puede causar un problema al acceder a un cierre modificado (tenga en cuenta que dije ''puedo'' no ''causará'' un problema porque a veces no sucede dependiendo de qué más hay en el método, y algunas veces realmente quiere acceder al cierre modificado).

Más información:

http://blogs.msdn.com/abhinaba/archive/2005/10/18/482180.aspx

Aún más información:

http://blogs.msdn.com/oldnewthing/archive/2006/08/02/686456.aspx

http://blogs.msdn.com/oldnewthing/archive/2006/08/03/687529.aspx

http://blogs.msdn.com/oldnewthing/archive/2006/08/04/688527.aspx