Я знаю, что это старый вопрос, но я недавно изучал замыкания и подумал, что пример кода может быть полезен. За кулисами компилятор генерирует класс, который представляет лексическое замыкание для вашего вызова функции. Вероятно, это выглядит примерно так:
private sealed class Closure
{
public string[] files;
public int i;
public bool YourAnonymousMethod(string name)
{
return name.Equals(this.files[this.i]);
}
}
Как уже упоминалось выше, ваша функция работает, потому что предикаты вызываются сразу после создания. Компилятор сгенерирует что-то вроде:
private string Works()
{
var closure = new Closure();
closure.files = new string[3];
closure.files[0] = "notfoo";
closure.files[1] = "bar";
closure.files[2] = "notbaz";
var arrayToSearch = new string[] { "foo", "bar", "baz" };
//this works, because the predicates are being executed during the loop
for (closure.i = 0; closure.i < closure.files.Length; closure.i++)
{
if (Array.Exists(arrayToSearch, closure.YourAnonymousMethod))
return closure.files[closure.i];
}
return null;
}
С другой стороны, если вы сохраните, а затем вызовете предикаты, вы увидите, что каждый отдельный вызов предикатов действительно будет вызывать один и тот же метод в одном и том же экземпляре класса замыкания и, следовательно, будет использовать то же значение для i.