static void Main(string[] args)
{
var s = 3;
Func<int, Func<int>> func =
x => () =>
{
return x;
};
var result1 = func(s);
func = null;
s = 5;
var result2 = result1();
Console.WriteLine(result2);
Console.ReadKey();
}
My understanding is that x is not actually declared as a variable eg. var x = 3. Instead, it’s passed into the outer function, which returns a function that returns the original value. At the time it is returning this, it creates a closure around x to remember its value. Then later on, if you alter s, it has no effect.
Is this right?
(Output is 3 by the way, which I’d expect).
Edit: here’s a diagram as to why I think it is

x=3 is passed into the func, and it returns a function that simply returns x. But x doesn’t exist in the inner function, only its parent, and its parent no longer exists after I make it null. Where is x stored, when the inner function is ran? It must create a closure from the parent.
Further clarification:
int s = 0;
Func<int, Func<int>> func =
x => () =>
{
return x;
};
for (s = 0; s < 5; s++)
{
var result1 = func(s);
var result2 = result1();
Console.WriteLine(result2);
};
Output is 0, 1, 2, 3, 4
However with your example:
static void Main(string[] args)
{
int s = 0;
Func<int, Func<int>> func =
x => () =>
{
return s;
};
List<Func<int>> results = new List<Func<int>>();
for (s = 0; s < 5; s++)
{
results.Add(func(s));
};
foreach (var b in results)
{
Console.WriteLine(b());
}
Console.ReadKey();
}
The output is 5 5 5 5 5, which isn’t what you want. It hasn’t captured the value of the variable, it’s merely retained a reference to the original s.
Closures are created in javascript precisely to avoid this problem.
No, that’s not a closure on
s,xis just an argument to the lambda expression which generates a delegate (which could actually be simplified tox => () => x.You’ll get
3and5as expected. In neither case does it actually rememberxfrom the other time, but it does close onxlocally during the duration of the outer lambda.Basically, each call to
x => () => xwill create a new() => xdelegate which captures the local value ofx(not of thespassed in).Even if you use
sand pass it in, and change it, you still get3and5:Now, it does capture on the local variable
xwithin the local function, which is generated at every call. So thexwon’t persist between invocations of the larger lambda, but it will be captured if changed later in the lambda.For example, let’s say instead you had this:
In this case, the closure on
xwithin the anonymous method is more obvious. The results of running this will be 30 and 50 because modifications toxwithin the anonymous method affect the closure on thexlocal to that anonymous method, however, these do not carry over between calls, because it’s only capturing the localxpassed into the anonymous method, and not thesused to call it.So, to sum up, in your diagram and example:
* main passes
sinto the larger lambda (func in your diagram)* func closes on
xat the time it’s called to generate the anonymous method() => xOnce the call to the outer lambda is made (func) the closer begins and ends because it’s local to that lambda only and doesn’t close on anything from main.
Does that help?