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
}
Powyższe wydaje się działać dobrze, chociaż ReSharper narzeka, że jest to „dostęp do zmodyfikowanego zamknięcia”. Czy ktoś może rzucić na to światło?
(ten temat kontynuowano tutaj )
Odpowiedzi:
W takim przypadku jest to w porządku, ponieważ faktycznie wykonujesz delegata w pętli.
Gdybyś jednak zapisywał delegata i używał go później, okazałoby się, że wszyscy delegaci rzuciliby wyjątki podczas próby uzyskania dostępu do plików [i] - przechwytują zmienną,
i
a nie jej wartość w momencie delegowania kreacja.Krótko mówiąc, jest to coś, o czym należy pamiętać jako potencjalna pułapka, ale w tym przypadku nie zaszkodzi ci to.
Zobacz na dole tej strony bardziej złożony przykład, w którym wyniki są sprzeczne z intuicją.
źródło
Wiem, że to stare pytanie, ale ostatnio studiowałem zamknięcia i pomyślałem, że próbka kodu może być przydatna. Za kulisami kompilator generuje klasę, która reprezentuje leksykalne zamknięcie twojego wywołania funkcji. Prawdopodobnie wygląda to tak:
Jak wspomniano powyżej, funkcja działa, ponieważ predykaty są wywoływane natychmiast po utworzeniu. Kompilator wygeneruje coś takiego:
Z drugiej strony, jeśli miałbyś zapisać, a następnie wywołać predykaty, zobaczyłbyś, że każde pojedyncze wywołanie predykatów naprawdę wywoływałoby tę samą metodę w tej samej instancji klasy zamknięcia, a zatem użyłby tej samej wartości dla ja.
źródło
„pliki” to przechwycona zmienna zewnętrzna, ponieważ została przechwycona przez anonimową funkcję delegowania. Jego żywotność jest przedłużana przez anonimową funkcję delegowania.
Zmienne zewnętrzne w MSDN
źródło