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

时间:2014-01-08 19:51:42

标签: c# scope

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

for (int x = 0; x < 9; x++) 
  {
     //something
  }
int x = 0;

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

for (int x = 0; x < 9; x++) 
  {
     //something
  }
x = 0;

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

7 个答案:

答案 0 :(得分: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) {}
    }
}

完全合法,即使同时在范围内有两个叫x的东西。但这不合法:

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

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

现在你的第二个错误:

  

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

名称x仅在for语句中有效。 for声明:

for (declarations ; condition ; increment ) body

在逻辑上等效(模数中断和继续行为)到

{
    declarations;
    while(condition)
    {
        body
        increment
    } 
}

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

答案 1 :(得分:6)

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

int x;
for (int x = 0; x < 9; x++) 
{
   //something
   // 'x' is ambiguous here
}
x = 0;

变量声明在C#中的工作方式与第一个样本相同。

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

答案 2 :(得分:5)

C#阻止你创建一个令人困惑的情况,在这种情况下,x实际引用的内容很容易出错。

答案 3 :(得分:0)

这不是矛盾。您在int x中定义的for的范围限定为for循环,意思是:

for (int x = 0; x < 9; x++) 
{
    //x is only alive here.
}

//you can't use it here.

但是您无法在父作用域(即方法作用域)中创建另一个 x变量:

public void MyMethod()
{
   int x = 0; //method-scoped variable.

    for (int x = 0; x < 9; x++)  //for-scoped variable, with the same name, invalid.
    {
        //here you have 2 "x", which one to use? invalid.
    }

   //the first x is available here
}

答案 4 :(得分:0)

由大括号括起来的一系列语句构成了一个代码块。方法体是代码块的一个示例。代码块通常遵循控制语句。在代码块中声明的变量或常量仅可用于同一代码块中的语句。

点击此链接:http://msdn.microsoft.com/en-us/library/ms173143%28v=vs.80%29.aspx

这样做:

for (int x = 0; x < 9; x++) 
  {
     //something
  }
x = 0;

语义分析器将其检测为错误,因为在for循环之外x不再可用。

虽然当你在内部块中执行int x并在内部块之外声明一个int x时,编译器会警告你只有你的语义可能出错。

for (int x = 0; x < 9; x++) 
  {
     //something
  }

//theoretically allowed, but the C# compiler identifies it as an error.
int x = 0; //caution x declare before

如果您对此感兴趣,解释非常简单:

如语言规范第3.7节所述。 “在local-variable-declaration(8.5.1)中声明的局部变量的范围是声明发生的块”。

x的范围因此是您声明它的整个函数,这意味着for循环之外的声明/使用是re = use,因此是不允许的。

此行为旨在不太可能重复使用变量名称(例如剪切和粘贴)。

问候。

答案 5 :(得分:0)

这是由于孩子的范围。

由于i's位于同一范围

,因此无效
for (int i = 0; i < 100; i++)
{
    Console.WriteLine(i);
}

int i = 10;
Console.WriteLine(i);

以下内容也无效,因为i's仍在同一范围内

{
    for (int i = 0; i < 100; i++)
    {
        Console.WriteLine(i);
    }
}
int i = 10;
Console.WriteLine(i);

以下工作会很好

{
    for (int i = 0; i < 100; i++)
    {
        Console.WriteLine(i);
    }
}
{
    int i = 10;
    Console.WriteLine(i);
}

答案 6 :(得分:-1)

变量x是我们的范围,因为它是在循环中声明的。如果你想再次使用相同的变量,试试这个 - (不推荐使用 - 标准明智)

int x = 0;
for (x = 0; x < 9; x++){
//something
}
x = 0;