c# - 我以为 C# 有词法作用域,但为什么这个例子显示动态作用域行为?

标签 c# scope

    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/

相关文章:

c# - 已签名的超值的解析器?

c++ - C++ 代码块的错误代码调试

Javascript 和 JQuery "this"范围错误

在本地范围内更改值

javascript - 为什么我的简单事件处理示例不起作用?

c# - 找不到库中的 WebDriver

c# - WebDavSharp 服务器。如何使用 Word 选项共享链接

ruby-on-rails - 在局部文件中本地定义的变量对于调用的 erb 模板是否也可见?

c# - Metro App,查询Windows Store中的当前应用

c# - 处理 WPF TextBox LostFocus 事件和绑定(bind)的顺序