Til*_*lak 6 .net c# linq closures anonymous-methods
Linq Query中声明的局部变量的范围是什么.
我正在编写以下代码
static void Evaluate()
{
var listNumbers = Enumerable.Range(1, 10).Select(i => i);
int i = 10;
}
Run Code Online (Sandbox Code Playgroud)
编译器标记的错误在行int i = 10,说明
A local variable named 'i' cannot be declared in this scope because it would give a different meaning to 'i', which is already used in a 'child' scope to denote something else
Run Code Online (Sandbox Code Playgroud)
我无法理解为什么会出现这个错误.
我的理解是,i在第一行之后(在foreach循环中)将超出范围.所以i可以再次宣布.
实际行为是i在第一行(在foreach循环中)之后无法访问,这是正确的.但i不能再宣布.这看起来很奇怪.
编辑这是基于安德拉斯的回应的以下问题.答案非常好,但会引起进一步的质疑.
static void Evaluate3()
{
var listNumbers = Enumerable.Range(1, 10).Select(i => i);
var listNumbers1 = Enumerable.Range(1, 10).Select(i => i);
}
Run Code Online (Sandbox Code Playgroud)
基于函数的逻辑评估.Select(i => i)和int i = 10,两者都是函数块的局部因而是复杂性错误.
函数Evaluate3不应该编译,因为方法块中有两个i,但它正在成功编译而没有任何警告/错误.
问题,Evaluate和Evaluate3都不应该编译,或者两者都应该编译.
这里要注意的关键事实是声明:
int i;
Run Code Online (Sandbox Code Playgroud)
... 从头到尾贯穿整个封闭范围- 不仅仅是从声明它的位置开始生效.在.Net中,局部变量的声明只是编译器为整个范围保留该名称和本地的指令.这意味着一旦声明,它就已经为所有线路保留了之前和之后.
实际上,这意味着您应该实际读Evaluate作:
static void Evaluate()
{
int i;
var listNumbers = Enumerable.Range(1, 10).Select(i => i);
i = 10;
}
Run Code Online (Sandbox Code Playgroud)
如果你相应地编写了你的方法,你会发现编译器错误发生在lambda声明上 - 这是完全合理的.值得庆幸的是,从人类的角度来看,C#编译器非常聪明,认识到代码的排序对我们很重要,它实际上将编译器错误分配给第二个或后续声明的任何源代码行; 因此,为什么你的版本Evaluate发生在线上int i = 10;.随着功能的本地的实际寿命这方面的知识i,编译器是正确的:使用i有将与先前使用的冲突i在lambda.
您可以使用显式范围来避免这种情况:
static void Evaluate()
{
var listNumbers = Enumerable.Range(1, 10).Select(i => i);
{
int i = 10;
}
}
Run Code Online (Sandbox Code Playgroud)
在Evaluate3你只是注意到两个lambdas共享父函数范围的情况下,它们也有自己的,并且它们在那里声明了它们i- 这就是为什么它们不相互干扰(它们实际上是,兄弟范围).
顺便提一下Evaluate,Evaluate3最终可以简化为:
static void Evaluate()
{
{
int i;
}
int i; //<-- error
}
static void Evaluate3()
{
{
int i;
}
{
int i;
}
//fine here - both i's are in different scopes.
}
Run Code Online (Sandbox Code Playgroud)
实际上这是我在此之前使用显式范围的第二个场景 - 也就是说,在同一个函数中的不同范围内,其中每个范围i实际上都有不同的类型.就像我说的 - 我再也没有这样做过,而且有问题的代码已不再存在了:)
| 归档时间: |
|
| 查看次数: |
1256 次 |
| 最近记录: |