I\'ve been reading this article about closures in which they say:
Your example isn't clear, and doesn't (IMO) show typical capture usage (the only thing captured is a
, which is always 3, so not very interesting).
Consider this text-book example (a predicate):
List<Person> people = ...
string nameToFind = ...
Person found = people.Find(person => person.Name == nameToFind);
Now try it without a closure; you need to do a lot more work, even if we are lazy:
PersonFinder finder = new PersonFinder();
finder.nameToFind = ...
Person found = people.Find(finder.IsMatch);
...
class PersonFinder {
public string nameToFind; // a public field to mirror the C# capture
public bool IsMatch(Person person) {
return person.Name == nameToFind;
}
}
The capture approach extends further to lots of variables at different scopes - a lot of complexity that is hidden.
Other than the names, the above is an approximation of what the C# compiler does behind the scenes. Note that when additional scopes are involved we start chaining the different capture classes (i.e. inner scopes have a reference to the capture class of outer scopes). Quite complex.
Jon Skeet has a good article on this here, and more in his book.
The closure is a functionality of the Compiler. You don't see it, it just makes the code you write work.
Without it, the call to AddToIt(3) will fail, because the underlying lamda uses the local variable a = 27 in the scope of AddToItClusure(). This variable is does not exist when AddToIt is called.
But because of the Closure, a mechanism used by the compiler, the code works and you don't have to care about it.