나는 최근에 이미 같은 이름의 변수가있는 함수 내에 선언 된 작업의 매개 변수로 변수 이름을 실수로 재사용하는 일부 코드를 작성했습니다. 예를 들면 다음과 같습니다.
var x = 1;
Action<int> myAction = (x) => { Console.WriteLine(x); };
중복을 발견했을 때 코드가 컴파일되고 완벽하게 실행되었다는 사실에 놀랐습니다. 이것은 C #의 범위에 대해 알고있는 것을 기반으로 기대되는 동작이 아닙니다. 일부 빠른 인터넷 검색은 유사한 코드 로 인해 Lambda Scope Clarification 과 같은 오류 가 발생 한다고 불평하는 SO 질문을 제기했습니다 . (저는 샘플 코드를 IDE에 붙여 넣어 실행 여부를 확인하고 완벽하게 실행합니다.) 또한 Visual Studio에서 이름 바꾸기 대화 상자를 시작하면 첫 번째 이름이 이름 충돌로 강조 표시됩니다.x
이 코드는 왜 작동합니까? Visual Studio 2019에서 C # 8을 사용하고 있습니다.
답변
이 코드는 왜 작동합니까? Visual Studio 2019에서 C # 8을 사용하고 있습니다.
당신은 당신의 자신의 질문에 대답했습니다! C # 8을 사용하고 있기 때문입니다.
C # 1에서 7까지의 규칙은 다음과 같습니다. 간단한 이름을 사용하여 동일한 로컬 범위에서 서로 다른 두 가지를 의미 할 수 없습니다. (실제 규칙은 그것보다 약간 더 복잡하지만 지루한 방법을 설명합니다. 자세한 내용은 C # 사양을 참조하십시오.)
이 규칙의 목적은 당신의 예에서 이야기하고있는 상황을 막는 것이 었습니다. 특히이 규칙은 다음과 같은 혼동을 방지하기 위해 고안되었습니다.
class C
{
int x;
void M()
{
x = 123;
if (whatever)
{
int x = 356;
...
그리고 지금 우리의 몸 내부의 상황이 곳이 M
, x
수단 모두 this.x
와 지역을 x
.
의도가 좋았지 만이 규칙에는 여러 가지 문제가있었습니다.
- 사양에 맞게 구현되지 않았습니다. 간단한 이름을 유형과 속성으로 사용할 수있는 상황이 있었지만 오류 감지 논리에 결함이 있기 때문에 항상 오류로 표시되지 않았습니다. (아래 참조)
- 오류 메시지가 혼란스럽게 표시되고 일관되지 않게보고되었습니다. 이 상황에 대해 여러 가지 다른 오류 메시지가있었습니다. 그들은 일관되게 범죄자를 식별했다. 즉, 때로는 내부 사용이 호출되고 때로는 외부 가 호출 되고 때로는 혼란 스러웠습니다.
나는 Roslyn을 다시 써서 이것을 정리하려고 노력했다. 새 오류 메시지를 추가하고 오류가보고 된 위치와 관련하여 이전 오류 메시지를 일관되게 만들었습니다. 그러나이 노력은 너무 적었고 너무 늦었다.
C # 팀은 C # 8에 대해 전체 규칙이 방지하는 것보다 더 많은 혼란을 야기하고 규칙에서 언어가 폐기되었다고 결정했습니다. (퇴직시기를 결정한 Jonathon Chase에게 감사드립니다.)
이 문제의 이력과이 문제를 해결하려는 방법에 관심이있는 경우, 내가 작성한이 기사를 참조하십시오.
https://ericlippert.com/2009/11/02/simple-names-are-not-so-simple/
https://ericlippert.com/2009/11/05/simple-names-are-not-so-simple-part-two/
https://ericlippert.com/2014/09/25/confusing-errors-for-a-confusing-feature-part-one/
https://ericlippert.com/2014/09/29/confusing-errors-for-a-confusing-feature-part-two/
https://ericlippert.com/2014/10/03/confusing-errors-for-a-confusing-feature-part-three/
3 부 끝에서이 기능과 “색상”기능, 즉 다음을 허용하는 기능간에 상호 작용이 있음을 언급했습니다.
class C
{
Color Color { get; set; }
void M()
{
Color = Color.Red;
}
}
여기서 우리는 간단한 이름 Color
을 사용 this.Color
하여 열거 된 형식과 둘 다를 참조했습니다 Color
. 사양을 엄격히 읽으면 오류가 발생하지만이 경우 사양이 잘못되어 의도가 허용됩니다.이 코드는 명확하지 않으며 개발자가 변경하게하기 때문에 까다로울 것입니다.
나는이 두 규칙 사이의 모든 이상한 상호 작용을 설명하는 기사를 쓰지 않았으며 지금 그렇게하는 것은 무의미합니다!