var x = 1;
Func<int,int> f = y => x + y;
x = 2;
Console.WriteLine(f(1));
输出是 3。根据 https://web.archive.org/web/20170426121932/http://www.cs.cornell.edu/~clarkson/courses/csci4223/2013sp/lec/lec12.pdf,我假设它是 2
最佳答案
PDF 没有完全解释有关词法范围的微妙之处。它的示例实际上有两个名为 x
的不同变量,它不会重新分配第一个 x
的值(实际上函数式语言可能不允许突变)。
C# 是词法范围的——它在 lambda 的定义点查找 x
,而不是在调用委托(delegate)时查找。但是:x
解析为一个变量,而不是一个值,它会在调用时读取变量的值。
这是一个更完整的例子:
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()));
lambda 绑定(bind)到DefineIt
内部 中存在的x
变量。定义点的值 (x = 1
) 无关紧要。 变量 稍后设置为 x = 3
。
但它显然也不是动态范围,因为InvokeIt
中的x = 2
没有被使用。
关于c# - 我以为 C# 有词法作用域,但为什么这个例子显示动态作用域行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16220698/