I found the following rather strange. Then again, I have mostly used closures in dynamic languages which shouldn\'t be suspectable to the same \"bug\". The following makes t
The "closure" created by an anonymous function is somewhat different from that created in other dynamic languages (I'll use Javascript as an example).
function thing() {
var o1 = {n:1}
var o2 = {dummy:"Hello"}
return function() { return o1.n++; }
}
var fn = thing();
alert(fn());
alert(fn());
This little chunk of javascript will display 1 then 2. The anonymous function can access the o1 variable because it exists on its scope chain. However the anonymous function has an entirely independant scope in which it could create another o1 variable and thereby hide any other further down the scope chain. Note also that all variables in the entire chain remain, hence o2 would continue to exist holding an object reference for as long as the fn varialbe holds the function reference.
Now compare with C# anonymous functions:-
class C1 { public int n {get; set;} }
class C2 { public string dummy { get; set; } }
Func thing() {
var o1 = new C1() {n=1};
var o2 = new C2() {dummy="Hello"};
return delegate { return o1.n++; };
}
...
Func fn = thing();
Console.WriteLine(fn());
Console.WriteLine(fn());
In this case the anonymous function is not creating a truely independant scope any more than variable declaration in any other in-function { } block of code would be (used in a foreach
, if
, etc.)
Hence the same rules apply, code outside the block cannot access variables declared inside the block but you cannot reuse an identifier either.
A closure is created when the anonymous function is passed outside of the function that it was created in. The variation from the Javascript example is that only those variables actually used by the anonymous function will remain, hence in this case the object held by o2 will be available for GC as soon as thing completes,