为什么我不能声明具有已经声明的相同名称的变量,但是新变量超出了其他变量的范围

时间:2012-03-12 07:23:14

标签: c# foreach scope

private void Abc()
{
    string first="";
    ArrayList result = new ArrayList();
    ArrayList secResult = new ArrayList();
    foreach (string second in result)
    {
        if (first != null)
        {
            foreach (string third in secResult)
            {
                string target;
            }
        }

        string target;//Here I cannot decalre it. And if I don't declare it and
        //want to use it then also I cannot use it. And if it is in if condition like
        //the code commented below, then there is no any complier error.
        //if (first != null)
        //{
        //    string target;
        //}
    }
}

我无法理解:为什么我不能在foreach循环之外声明变量,因为编译器会给出一个已经声明变量的错误。 foreach(以及target变量)的范围已经结束,我宣布这个新变量。

2 个答案:

答案 0 :(得分:9)

局部变量的范围一直延伸到声明它的块的开头。因此,第二个声明的范围实际上是整个外部foreach循环。从C#4规范,第3.7节:

  

在local-variable-declaration(第8.5.1节)中声明的局部变量的范围是声明发生的块。

和第8.5.1节:

  

在local-variable-declaration中声明的局部变量的范围是声明发生的块。在局部变量的local-variable-declarator之前的文本位置引用局部变量是错误的。在局部变量的范围内,声明另一个具有相同名称的局部变量或常量是编译时错误。

因此即使第二个变量尚未在第一个变量发生的位置声明,它仍然在范围内 - 因此它们之间的两个声明违反了8.5.1。

语言的设计是为了防止错误 - 如果只是在声明的块中移动局部变量声明的位置并在第一次使用之前改变了有效性,那就太奇怪了。代码。

答案 1 :(得分:2)

这是因为第二个声明是针对第一个foreach循环的方法范围的整个范围,其中包含方法中包含的第二个foreach循环。所以你需要的是使用大括号来限制另一个字符串的范围

{
string target .....
}

这不应该是真正需要的,似乎是代码味道的标志,也许你需要将逻辑封装到单独的方法中。我会要求你再次审查代码,看看它是否可以重建。