C# 无法在此作用域[Linq/Lambda expression]中声明局部变量
我有以下c语言的代码片段# 当我编译上面的代码时,我得到了以下错误 无法在此范围内声明名为“n”的局部变量您的问题在于:C# 无法在此作用域[Linq/Lambda expression]中声明局部变量,c#,linq,C#,Linq,我有以下c语言的代码片段# 当我编译上面的代码时,我得到了以下错误 无法在此范围内声明名为“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(); 为了理解为什么这是一个问题,请考虑下
// 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选择一个不同的变量名;e、 g:
var ngt5 = numbers.Where(x => x > 5);
你的问题是你假设闭包是C#中的第一类函数,事实并非如此,我希望是这样 不能将C#闭包的作用域视为孤立的函数作用域 不能返回当前范围之外的复杂Linq表达式
JavaScript允许这种模糊性,允许无限制地编写闭包,这使得闭包成为JavaScript的第一类函数。这段代码的上下文是什么?@Tobias:我修改了我的code@Dan:你的意思是lambda变量是全局变量?@Dan:抱歉这个愚蠢的问题……我们能说这是c#bug吗?@geek:我不同意。你认为这种行为的“错误”是什么?从我的角度来看,编译器似乎在阻止您编写含糊不清的代码,这是一件好事。@Dan:非常感谢您澄清我的疑问……:)JavaScript允许这种含糊不清的代码,它允许无限制地编写闭包。通过施加这一限制,C#不允许像JavaScript一样将闭包用作第一类函数。
var ngt5 = numbers.Where(x => x > 5);