Lambda范围澄清

Joe*_*Joe 22 .net c# lambda scope c#-4.0

为什么我的参数x表现得如此不规律?

  1. 示例1 - 当前上下文中不存在.
  2. 示例2 - 无法重用,x因为它是在"子"范围内定义的.
  3. 例3 - 很好.这是我感到困惑的部分.也许是一个不同的"孩子"范围?

例1:

List<int> list = new List<int> { 1, 2, 3, 4, 5 };
var result = list.Where(x => x < 3);
Console.Write(result.ElementAt(x));
Run Code Online (Sandbox Code Playgroud)

创建此编译时错误:

当前上下文中不存在名称"x"

我期待的.

例2:

List<int> list = new List<int> { 1, 2, 3, 4, 5 };
var result = list.Where(x => x < 3);
int x = 1;
Console.Write(result.ElementAt(x));
Run Code Online (Sandbox Code Playgroud)

产生这个编译时错误:

名为'x'的局部变量不能在此范围内声明,因为它会给'x'赋予不同的含义,'x'已在'子'范围内用于表示其他内容

我理解在这个问题中回答的范围,C#在foreach中重用变量是否有原因?.然而,这是我以前从未见过的.另外,它回答了这个问题,C#中lambda变量的范围是什么?,不完整或错误.

例3:

List<int> list = new List<int> { 1, 2, 3, 4, 5 };
List<string> stringList = new List<string> { "A", "B" };
var result = list.Where(x => x < 3);
var result2 = stringList.Where(x => x != "A");

Console.Write(result2);
Run Code Online (Sandbox Code Playgroud)

没有产生错误.


通过接受的答案,Eric Lippert的这些博客文章帮助我了解了正在发生的事情.如果有人仍然困惑:

宣言空间

简单的名字

Pet*_*hie 18

Example 1,x是在lamdba表达式的局部范围内定义的,并且对第三行不可见

Example 2,现在你已经在同一声明范围内声明了两个名为"x"的变量(可见性不同)

使用lambda或匿名方法,它"捕获"它运行的范围.如果你有一个与lambda定义相同范围的本地x,那么它"捕获"x以拉入lambda可以访问的内容 - 从而产生两个"x"定义.你在lambda中声明的内容不会被捕获到另一个方向,因此它在lambda外部不可见.

Example 3,现在你没有使用本地的变量只是lambda之外的lambda,而不是在同一声明范围内命名相同的东西.

  • @MrClan它没有编译,因为"x => ..."声明了一个x变量,而"int x = 1;" 宣布另一个.lambda是一个闭包,它可以引入在执行lambda时捕获的"外部变量".为了捕获这些变量,它们必须是唯一的."x"可以表示在lambda中定义的x,或者在外部作用域中定义的x - 因此,编译器不知道在"x <3"代码中使用哪个... (3认同)

Ale*_*kov 5

子范围(示例3)可以使用相同的变量,但父级和子级不能重新声明变量.

您可以获得相同的:

// Child scopes
for (int i = 1; i < 10; i++){ /* do something */ }
for (int i = 1; i < 10; i++){ /* do something else */ }
Run Code Online (Sandbox Code Playgroud)

这会失败:

// Child and parent
for (int i = 1; i < 10; i++){ /* do something */ }
int i = 33;
Run Code Online (Sandbox Code Playgroud)