的局部变量不能在此范围中声明[LINQ的/ Lambda表达式]
我有以下代码段的局部变量不能在此范围中声明[LINQ的/ Lambda表达式]
static void Main()
{
var numbers = new[] { 1, 2, 3, 4, 5, 6 };
var ngt5 = numbers.Where(n => n > 5);
var n = ngt5.First().ToString();
Console.WriteLine(n, numbers);
}
当我编译上述代码我得到以下错误
甲命名为“N”的局部变量不能在此范围内声明
你的问题是在这里:
// Within your lambda you have an 'n'.
var ngt5 = numbers.Where(n => n > 5);
// And within the outer scope you also have an 'n'.
var n = ngt5.First().ToString();
要理解为什么这是一个问题,考虑下面的代码:
int n = 1000;
var evens = Enumerable.Range(1, 1000).Where(n => n % 2 == 0);
表达上述n % 2 == 0
是不明确的:这n
,我们谈论的?如果我们谈论的外n
,然后n % 2 == 0
是总是如此,因为n
仅仅是1000(因此evens
将包括所有号码从1到1000)。另一方面,如果我们在谈论内部n
,那么n % 2 == 0
将只对n
(和evens
将是2,4,6,... 1000)的偶数值保持为真。
要实现的重要一点是,在lambda之外声明的变量可以从lambda范围内访问。
int n = 0;
Action incrementN =() => n++; // accessing an outer variable
incrementN();
Console.WriteLine(n); // outputs '1'
这就是为什么存在不确定性,以及为什么它因此不允许的。
解决方法是简单地为您的lambda选择一个不同的变量名;例如:
var ngt5 = numbers.Where(x => x > 5);
@Dan:你的意思是lambda变量是全局的吗? – 2011-05-27 17:35:10
@geek:不,它不是全球性的。我会更新我的答案,以更好地解释... – 2011-05-27 17:36:48
@丹涛:好的先生 – 2011-05-27 17:37:53
你的问题是,你认为闭包是C#中的第一类函数,情况并非如此,我希望它是这种情况。
您不能将C#闭包的作用域视为独立的函数作用域。
您不能在当前范围外返回复杂的Linq表达式。
JavaScript允许这种含糊不清,它允许无限制地编写闭包,这使闭包JavaScript的一流功能成为可能。
这段代码的上下文是什么? – SirPentor 2011-05-27 17:31:10
@Tobias:我修改了我的代码 – 2011-05-27 17:33:24