Visual Studio null 참조 경고 - 오류가없는 이유는 무엇입니까?
-
06-07-2019 - |
문제
나는 Visual Studio에 대해 독특한 것을 발견했습니다. 먼저 함수 어딘가에 이것 (c#)을 입력하십시오.
class Foo
{
public void Bar()
{
string s;
int i = s.Length;
}
}
이제 바로 표시됩니다 s
안에 s.Length
오류로 "Use of unassigned local variable 's'
". 반면 에이 코드를 시도하십시오.
class Foo
{
private string s;
public void Bar()
{
int i = s.Length;
}
}
컴파일하고 밑줄이 듭니다 s
안에 private string s
경고로 "Field 'Foo.s' is never assigned to, and will always have its default value null
".
자, VS가 그 똑똑하고 S가 항상 널이 될 것이라는 것을 알고 있다면 두 번째 예에서 길이를 얻는 것이 오류가 아닌 이유는 무엇입니까? 내 원래 추측은 "컴파일러가 단순히 작업을 완료 할 수없는 경우에만 컴파일 오류 만 제공합니다. 코드는 Bar () 호출하지 않는 한 기술적으로 실행되므로 경고 일뿐입니다." 그 설명은 첫 번째 예에 의해 무효화됩니다. Bar ()를 호출하지 않는 한 여전히 오류없이 코드를 실행할 수 있습니다. 그래서 무엇을 제공합니까? 단지 감독입니까, 아니면 내가 뭔가를 놓치고 있습니까?
해결책
첫 번째 예제 (오류)는 컴파일러의 예입니다. 명확한 할당 추적 및 이는 로컬 변수에만 적용됩니다. 제한된 컨텍스트로 인해 컴파일러는이 상황에 밀폐 된 그립을 갖습니다. 주목하십시오 s
무효가 아니며 정의되지 않았습니다.
두 번째 예에서 s
필드입니다 (및 기본값은 NULL)입니다. 컴파일러 오류는 없지만 항상 런타임에 잡히게됩니다. 이 특정 사례는 갇힐 수 있지만 이러한 종류의 오류는 일반적으로 컴파일러에 의해 감지 할 수 없습니다.
예를 들어 메소드를 추가 할 수 있습니다 Bar2()
문자열을 할당합니다 s
그러나 나중에 전화하십시오 Bar()
, 또는 전혀. 그러면 경고는 제거되지만 런타임 오류는 아닙니다.
그래서 그것은 디자인에 의한 것입니다.
다른 팁
두 번째 예제의 경우 코드가 유효합니다. 올바르게 실행되지 않을 수 있습니다. 이 프로그램이 "성공적으로"실행할 수있는 몇 가지 사례가 있습니다.
- 컴파일러는 100% 정확하지 않습니다. 인스턴스가 반사를 통해 수정되면 "S"가 널 값이 아닌 값을 가질 수 있습니다.
- 메소드 막대가 호출되지 않으면 프로그램이 오류없이 실행할 수 있습니다.
- 이 프로그램은 테스트 이유에 대한 NullReferenceException을 유발하는 테스트 프로그램 일 수 있습니다.
내가 할 수있는 유일한 추측은 두 번째 예에서 S는 반사를 통해 변경 될 수 있다는 것입니다 (Bindingflags.private를 사용하여 개인 구성원에게 액세스 할 수 있음).
첫 번째 샘플에서 에스 로컬 변수이며 컴파일러는 에스 변수는 사용하기 전에 할당되지 않았습니다.
두 번째로 에스 글로벌 변수이며 클래스의 다른 곳에서 초기화되었을 수 있습니다.