string [] files = new string[2];
files[0] = "ThinkFarAhead.Example.Settings.Configuration_Local.xml";
files[1] = "ThinkFarAhead.Example.Settings.Configuration_Global.xml";
//Resharper complains this is an "access to modified closure"
for (int i = 0; i < files.Length; i++ )
{
// Resharper disable AccessToModifiedClosure
if(Array.Exists(Assembly.GetExecutingAssembly().GetManifestResourceNames(),
delegate(string name) { return name.Equals(files[i]); }))
return Assembly.GetExecutingAssembly().GetManifestResourceStream(files[i]);
// ReSharper restore AccessToModifiedClosure
}
Lo anterior parece funcionar bien, aunque ReSharper se queja de que esto es "acceso al cierre modificado". ¿Alguien puede arrojar luz sobre esto?
(este tema continuó aquí )
Respuestas:
En este caso, está bien, ya que en realidad está ejecutando el delegado dentro del bucle.
Sin embargo, si guardara el delegado y lo usara más tarde, descubriría que todos los delegados arrojarían excepciones al intentar acceder a los archivos [i]: están capturando la variable en
i
lugar de su valor en el momento de los delegados. creación.En resumen, es algo a tener en cuenta como una trampa potencial , pero en este caso no te hace daño.
Consulte la parte inferior de esta página para ver un ejemplo más complejo en el que los resultados son contradictorios.
fuente
Sé que esta es una vieja pregunta, pero recientemente he estado estudiando cierres y pensé que una muestra de código podría ser útil. Detrás de escena, el compilador está generando una clase que representa un cierre léxico para su llamada a la función. Probablemente se parece a algo como:
Como se mencionó anteriormente, su función funciona porque los predicados se invocan inmediatamente después de la creación. El compilador generará algo como:
Por otro lado, si tuviera que almacenar y luego invocar los predicados, vería que cada llamada a los predicados realmente llamaría al mismo método en la misma instancia de la clase de cierre y, por lo tanto, usaría el mismo valor para yo.
fuente
"archivos" es una variable externa capturada porque ha sido capturada por la función de delegado anónimo. Su vida útil se extiende por la función de delegado anónimo.
Variables externas en MSDN
fuente