2
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;
        //}
    }
}

I cannot understand: Why can't I declare the variable outside the foreach loop, as compiler gives an error that the variable is already declared. The scope of the foreach (and hence the target variable) is over where I am declaring this new variable.

Christos
  • 53,228
  • 8
  • 76
  • 108
Harikrishna
  • 4,185
  • 17
  • 57
  • 79
  • 1
    that's by choice - the complier want to help you from doing some pretty common errors. F# for example does allow something like this (even in the same scope) but there it helps the immutable/functional-paradigm – Random Dev Mar 12 '12 at 07:27
  • Although this is good question there are a lot of duplicates here. One of them: http://stackoverflow.com/questions/2059210/using-a-variable-name-used-in-a-child-scope. – Kirill Mar 12 '12 at 07:30

2 Answers2

9

The scope of a local variable extends all the way up to the start of the block in which it's declared. So the scope of your second declaration as actually the whole of the outer foreach loop. From the C# 4 spec, section 3.7:

The scope of a local variable declared in a local-variable-declaration (§8.5.1) is the block in which the declaration occurs.

and in section 8.5.1:

The scope of a local variable declared in a local-variable-declaration is the block in which the declaration occurs. It is an error to refer to a local variable in a textual position that precedes the local-variable-declarator of the local variable. Within the scope of a local variable, it is a compile-time error to declare another local variable or constant with the same name.

So even though the second variable hasn't been declared at the point where the first variable occurs, it's still in scope - so the two declarations between them violate 8.5.1.

The language was designed this way to prevent errors - it would be odd if simply moving the location of a local variable declaration within the block in which it's declared and before its first use changed the validity of the code.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Sir why should we not able to use it(first declared variable) then or if second variable is within one if block then compiler does not give any error ? – Harikrishna Mar 12 '12 at 07:37
  • @Harikrishna: It's hard to parse your comment, but if you've got an extra `if` block then that limits the scope of the second declaration further - read the sections of the spec I quoted. – Jon Skeet Mar 12 '12 at 07:41
  • What I wanted to ask is that why cannot we use first declared variable like target = "aa" out of that first if block ? – Harikrishna Mar 12 '12 at 08:53
  • @Harikrishna: Sorry, I still didn't understand your comment... but I think my answer explains the compile-time error you're seeing. – Jon Skeet Mar 12 '12 at 09:15
2

That is because the second declaration is for the entire scope of the method scope of the first foreach loop which includes the second foreach loop contained in the method. so what you need is to restrict the scope of the other string using braces

{
string target .....
}

Well this shouldn't be really required and seems like a sign of code smell, maybe you need to encapsulate the logic into separate methods. i would request you to review the code again and see if it could be reconstructed.

V4Vendetta
  • 37,194
  • 9
  • 78
  • 82
  • No, the second declaration is the scope of the foreach loop, not the whole method. The scope of a local variable is the block in which it's declared - see my answer. – Jon Skeet Mar 12 '12 at 07:42
  • @JonSkeet Thanks for pointing it out, wrong in determining the ending braces – V4Vendetta Mar 12 '12 at 08:48