Access to Modified Closure

Solution 1:

In this case, it's okay, since you are actually executing the delegate within the loop.

If you were saving the delegate and using it later, however, you'd find that all of the delegates would throw exceptions when trying to access files[i] - they're capturing the variable i rather than its value at the time of the delegates creation.

In short, it's something to be aware of as a potential trap, but in this case it doesn't hurt you.

See the bottom of this page for a more complex example where the results are counterintuitive.

Solution 2:

I know this is an old question, but I've recently been studying closures and thought a code sample might be useful. Behind the scenes, the compiler is generating a class that represents a lexical closure for your function call. It probably looks something like:

private sealed class Closure
{
    public string[] files;
    public int i;

    public bool YourAnonymousMethod(string name)
    {
        return name.Equals(this.files[this.i]);
    }
}

As mentioned above, your function works because the predicates are invoked immediately after creation. The compiler will generate something like:

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;
}

On the other hand, if you were to store and then later invoke the predicates, you would see that every single call to the predicates would really be calling the same method on the same instance of the closure class and therefore would use the same value for i.