for-loop에 선언 된 변수는 지역 변수입니까?
C #을 오랫동안 사용해 왔지만 다음을 깨달은 적이 없습니다.
public static void Main()
{
for (int i = 0; i < 5; i++)
{
}
int i = 4; //cannot declare as 'i' is declared in child scope
int A = i; //cannot assign as 'i' does not exist in this context
}
그렇다면이 이름으로 변수를 선언 할 수 없다면 for 블록 외부에서 'i'값을 사용할 수없는 이유는 무엇입니까?
for-loop가 사용하는 반복자 변수는 해당 범위에서만 유효하다고 생각했습니다.
for-loop 외부와 for-loop 외부에서 동일한 이름의 변수를 정의 할 수없는 이유는 외부 범위의 변수가 내부 범위에서 유효하기 때문입니다. 이것이 허용된다면 for-loop 내에 두 개의 'i'변수가 있음을 의미합니다.
참조 : MSDN 범위
구체적으로 특별히:
local-variable-declaration (8.5.1 절)에 선언 된 지역 변수의 범위는 선언이 발생하는 블록입니다.
과
for 문의 초기화에 대해 선언 된 지역 변수의 범위 (섹션 8.8.3)는 초기화 장치, 조건, for-iterator 및 for 문의 포함 명령문입니다.
또한 지역 변수 선언 (C # 사양의 섹션 8.5.1)
구체적으로 특별히:
local-variable-declaration에 선언 된 로컬 변수의 범위는 선언이 발생하는 블록입니다. 로컬 변수의 로컬 변수 선언 앞에있는 텍스트 위치에서 로컬 변수를 참조하면 오류가 발생합니다. 지역 변수의 범위 내에서 같은 이름으로 다른 지역 변수 나 상수를 선언하는 것은 컴파일 타임 오류입니다.
(Emphasis mine.)
이는 i
for 루프 내부 의 범위가 for 루프 임을 의미합니다 . i
for-loop 외부의 범위 는 전체 주요 방법 과 for-loop입니다. 의미 i
는 위와 같이 유효하지 않은 루프 내부에 두 번 발생 한다는 의미 입니다.
허용되지 않는 이유 는 루프 내에서만 사용할 수 int A = i;
있기 때문 int i
입니다 for
. 따라서 더 이상 for
루프 외부에서 액세스 할 수 없습니다 .
보시다시피이 두 가지 문제는 범위를 벗어난 결과입니다. 첫 번째 문제 ( int i = 4;
)는 루프 범위 i
내 에서 두 개의 변수를 생성합니다 for
. 반면 int A = i;
범위를 벗어난 변수에 액세스 할 수 있습니다.
대신 할 수있는 i
것은 전체 메소드에 범위가 지정되어 선언 하고 메소드와 for 루프 범위 모두에서 사용하는 것입니다. 이렇게하면 규칙을 어 기지 않아도됩니다.
public static void Main()
{
int i;
for (i = 0; i < 5; i++)
{
}
// 'i' is only declared in the method scope now,
// no longer in the child scope -> valid.
i = 4;
// 'i' is declared in the method's scope -> valid.
int A = i;
}
편집 :
물론 C # 컴파일러는이 코드가 상당히 유효하게 컴파일되도록 변경 될 수 있습니다. 결국 이것은 유효합니다 :
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
}
for (int i = 5; i > 0; i--)
{
Console.WriteLine(i);
}
그러나 코드 가독성 및 유지 관리가 다음과 같은 코드를 작성할 수 있다면 실제로 도움이 될 것입니다.
public static void Main()
{
int i = 4;
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
}
for (int i = 5; i > 0; i--)
{
Console.WriteLine(i);
}
Console.WriteLine(i);
}
여기서 실수의 가능성에 대해 생각해보십시오. 마지막으로 i
0이나 4를 인쇄합니까? 이제 이것은 매우 작은 예입니다. 추적하기 쉽고 추적하기 쉽지만 외부 i
이름을 다른 이름으로 선언 한 것보다 유지 관리가 쉽고 읽기 쉽습니다 .
NB :
Please note, C#'s scoping rules differ from C++'s scoping rules. In C++ variables are only in scope from where they are declared until the end of the block. Which would make your code a valid construct in C++.
J.Kommer's answer is correct: briefly, it is illegal for a local variable to be declared in a local variable declaration space that overlaps another local variable declaration space that has a local of the same name.
There is an additional rule of C# that is violated here as well. The additional rule is that it is illegal for a simple name to be used to refer to two different entities inside two different overlapping local variable declaration spaces. So not only is your example illegal, this is illegal too:
class C
{
int x;
void M()
{
int y = x;
if(whatever)
{
int x = 123;
Because now the simple name "x" has been used inside the local variable declaration space of "y" to mean two different things -- "this.x" and the local "x".
See http://blogs.msdn.com/b/ericlippert/archive/tags/simple+names/ for more analysis of these issues.
There is a way of declaring and using i
inside the method after the loop:
static void Main()
{
for (int i = 0; i < 5; i++)
{
}
{
int i = 4;
int A = i;
}
}
You can do this in Java (it might originate from C I'm not sure). It is of course a bit messy for the sake of a variable name.
If you'd declared i
before your for
loop, do you think it should still be valid to declare it inside the loop?
No, because then the scope of the two would overlap.
As for not being able to do int A=i;
, well that's simply because i
only exists in the for
loop, like it should do.
In addition to J.Kommer's answer (+1 btw). There's this in the standard for NET scope:
block If you declare a variable within a block construct such as an If statement, that variable's scope is only until the end of the block. The lifetime is until the procedure ends.
Procedure If you declare a variable within a procedure, but outside of any If statement, the scope is until the End Sub or End Function. The lifetime of the variable is until the procedures ends.
Thus the int i decalared within the for loop header will be in scope only during the for loop block, BUT it's lifetime lasts until the Main()
code completes.
The easiest way to think about this is to move the outer declaration of I to above the loop. It should become obvious then.
It's the same scope either way, therefore can't be done.
Also C#'s rules are many time not necessary in terms of programing strictly, but are there to keep your code clean and readable.
for example, they could have made it so that if you define it after the loop then it is ok, however it someone who reads your code and missed the definition line may think it has to do with the loop's variable.
Kommer's answer is technically correct. Let me paraphrase it with a vivid blind-screen metaphor.
There is a one way blind screen between the for-block and the enclosing outer block such that the code from within the for-block can see the outer code but the code in the outer block cannot see the code inside.
Since the outer code cannot see inside , it cannot use anything declared inside. But since the code in the for-block can see both inside and outside , a variable declared at both places cannot be used unambiguously by name.
So either you don't see it , or you C# !
Look at it in the same way as if you could declare an int
in a using
block:
using (int i = 0) {
// i is in scope here
}
// here, i is out of scope
However, since int
does not implement IDisposable
, this can not be done. It may help someone visualize how an int
variable is placed in a private scope, though.
Another way would be to say,
if (true) {
int i = 0;
// i is in scope here
}
// here, i is out of scope
Hope this helps to visualize what is going on.
I really like this feature, as declaring the int
from inside the for
loop keeps the code nice and tight.
참고URL : https://stackoverflow.com/questions/7992332/variable-declared-in-for-loop-is-local-variable
'IT' 카테고리의 다른 글
여러 스레드에서 java.util.HashMap의 값을 얻는 것이 안전합니까? (0) | 2020.06.27 |
---|---|
시스템 글꼴 및 dpi 설정으로 자동 확장되는 WinForms 코드를 작성하는 방법은 무엇입니까? (0) | 2020.06.27 |
vimdiff를 사용하여 자식 병합 충돌을 어떻게 해결합니까? (0) | 2020.06.27 |
React에서 DOM 요소에 액세스하는 방법? (0) | 2020.06.27 |
오류 :“반환 값을 수정할 수 없습니다”c # (0) | 2020.06.27 |