对于循环计数器,变量范围似乎具有双重个性?

use*_*847 6 c# scope

下面的代码在Visual Studio 2012中生成此错误; "名为'x'的局部变量不能在此范围内声明,因为它会给'x'赋予不同的含义,'x'已在'子'范围内用于表示其他内容"

for (int x = 0; x < 9; x++) 
  {
     //something
  }
int x = 0;
Run Code Online (Sandbox Code Playgroud)

然而.如下修改我得到这个错误; "当前上下文中不存在名称'x'"

for (int x = 0; x < 9; x++) 
  {
     //something
  }
x = 0;
Run Code Online (Sandbox Code Playgroud)

这是一个巨大的矛盾还是我错过了什么?

Eri*_*ert 11

到目前为止,除了Rik之外没有人指出正确的答案.

非常仔细地再次阅读错误消息.他们清楚地解释了错误.第一个错误是:

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

实际上阅读错误消息.它说使用相同的名称来表示两种不同的东西是非法的.该错误与外部x本身的范围无关; 它与在同一外部范围内x用于表示两件事物的事实有关.

正如Rik指出的那样,这条规则的目的是避免开发人员对其含义感到困惑的情况x.给定的名称在整个块中几乎总是意味着相同的东西.(有一些细微的例外,但我们今天不要讨论它们.)这条规则还有助于防止在方法中重新排序语句引入的错误,从而巧妙地改变名称的含义.如果名称的含义在块内是不变的,则可以放心地在该块内编辑代码.

许多答案都说不允许范围重叠.对,他们是. 不允许局部变量范围重叠,但允许范围重叠.例如:

class C
{
    int x;
    void M()
    {
        int y = this.x;
        for(int x = 0; x < 10; ++x) {}
    }
}
Run Code Online (Sandbox Code Playgroud)

尽管同时x在范围内有两个东西,但是完全合法.但这不合法:

class C
{
    int x;
    void M()
    {
        int y = x; // Means this.x
        for(int x = 0; x < 10; ++x) {} // means local x
    }
}
Run Code Online (Sandbox Code Playgroud)

现在简单的名字x意味着M体内有两种不同的东西,这就是非法的.同样,请确保您理解这一点:使用相同的名称来表示同一范围内的两件事是非法的.这是不是非法的重叠范围.

现在你的第二个错误:

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

该名称x仅在for声明中有效.一个for语句:

for (declarations ; condition ; increment ) body
Run Code Online (Sandbox Code Playgroud)

在逻辑上是等价的(模数中断和继续行为)

{
    declarations;
    while(condition)
    {
        body
        increment
    } 
}
Run Code Online (Sandbox Code Playgroud)

注意外括号.该声明中的任何内容都可以在整个条件,正文或增量中使用,但不在范围之外.


Joe*_*orn 6

第一个是错误,因为它等同于:

int x;
for (int x = 0; x < 9; x++) 
{
   //something
   // 'x' is ambiguous here
}
x = 0;
Run Code Online (Sandbox Code Playgroud)

变量声明在C#中的工作方式与第一个示例相同.

第二个是错误,因为循环中定义的'x'变量仅在循环中有效.

  • 这里违反的规则与外部x在范围内的位置无关!考虑例如`class C {int x; void M(){int y = x; for(int x = 0 ;;){}}`.这也是非法的,出于同样的原因.但它与外部`x`的范围无关!考虑`class C {int x; void M(){int y = this.x; for(int x = 0 ;;){}}`即使外部的"x"在整个范围内,这也是完全合法的!这里的违规是*简单名称*`x`不能用于表示同一范围内的两个不同的东西,而不是范围重叠.范围可以重叠. (4认同)

Rik*_*Rik 5

C#阻止你创建一个令人困惑的情况,在这种情况下很容易犯错误x.