var x = 1;
Func<int,int> f = y => x + y;
x = 2;
Console.WriteLine(f(1));
The output is 3. I would assume it is 2, according to https://web.archive.org/web/20170426121932/http://www.cs.cornell.edu/~clarkson/courses/csci4223/2013sp/lec/lec12.pdf
There's a subtlety concerning lexical scoping that PDF doesn't fully explain. Its example actually has two different variables named x
, it does not reassign the value of the first x
(and indeed functional languages may not allow mutation).
C# is lexically scoped -- it looks up x
at the point of definition of the lambda, not when the delegate is invoked. But: x
resolves to a variable, not a value, and it reads the variable's value at the time of invocation.
Here is a more complete example:
int InvokeIt( Func<int, int> f )
{
int x = 2;
return f(1);
}
Func<int, int> DefineIt()
{
int x = 1;
Func<int, int> d = (y => x + y);
x = 3; // <-- the PDF never does this
return d;
}
Console.WriteLine(InvokeIt(DefineIt()));
The lambda binds to the x
variable that exists inside DefineIt
. The value (x = 1
) at the point of definition is irrelevant. The variable is later set to x = 3
.
But it is clearly not dynamic scope either, because the x = 2
inside InvokeIt
is not used.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With