我读了这个问题(What is the scope of a lambda variable in C#?)
但它是关于LINQ Query中的Lambda变量范围。
现在回答我的问题
假设我有一个非常简单的LINQ查询。
var Foo = FoobBar.Select(x => x);
var x = somefunction();
编译说:A local variable 'x' cannot be declared in this scope because it would give a different meaning to 'x', which is already used in a 'child' scope to denote something else
。
为什么会这样?当LINQ查询结束时,Lambda变量是否应该不存在?
编辑:在阅读完答案后,我得出的结论是外部x
(从函数返回),其范围扩展到LINQ查询中。
答案 0 :(得分:9)
这不是LINQ关于儿童范围的问题。
例如:
foreach (var bar in FooBar.Bars)
{
var x = FooBar.GetFoo();
}
var x = new Foo();
从编译器生成完全相同的错误消息。
要解决这个问题,您只需将变量放在不同的(非嵌套)范围内即可。例如:
foreach (var bar in FooBar.Bars)
{
var x = FooBar.GetBar();
}
{
var x = new Foo();
}
答案 1 :(得分:4)
让我们仔细看看,
var Foo = FoobBar.Select(x => x);
如果x的范围以表达式
结尾var x = somefunction()
现在这很有趣,这是针对包含lamda表达式的整个方法的范围,因此编译器无法区分,因为后者的范围与前者重叠。还有非常有用的信息给'x'赋予不同的含义,已经在'子'范围内使用 (在您的情况下选择)
也许你可以在另一个周围包括大括号,以便定义范围
{
var x = somefunction()
}
答案 2 :(得分:2)
想想C#是否允许这两个变量存在于同一范围级别,这是不可能的:
static void test() {
Action<int> x = (z) => {
Console.WriteLine(z);
};
int[] i = { 5,2,0,1,3,1,4 };
var kyrie = i.Select (x => x);
}
如何对C#说你想将名为x的Action委托分配给kyrie变量;反之亦然,你会如何对C#说你想使用整数投影本身? C#将如何解决这个问题?
无论是在其他变量之前还是在其他变量之后声明它,它们都是相同的,C#范围解析是非常一致的。例如http://www.anicehumble.com/2012/05/java-said-c-said-scope-consistency.html
为了消除这些情况的歧义,C#不允许您编译具有在同一级别上存在的变量名称的程序
一切都是以非模糊方式向编译器表达 intent 。 C#在这方面做得很好
答案 3 :(得分:1)
(编译器)不清楚第二个'x'(=>
之后)的'x'是什么意思。
如果你写了这个怎么办:
var Foo = FoobBar.Select(y => x);
var x = somefunction();
然后lambda中的x
会与'somefunction'结果发生冲突。
答案 4 :(得分:1)
您不能在同一范围内声明两个具有相同名称的变量。
“相同范围”意味着它们都在当前范围内
void method()
{
int a;
int a; //wrong!
}
或者一个在当前,另一个在子范围内。
void method()
{
int a;
for(;;)
{
int a; //wrong again!
}
}
这是设计并适用于从int
s到lambda引用的任何变量。