2008-09-15 1 views
5
내가 예를 들어 int을 사용하고

, 그러나 이것은 컴파일러의 예외를 던질 것입니다 다음 닷넷 (1)에서 닷넷.Net 2+ : 왜 (1 == null)이 더 이상 컴파일러 예외를 throw하지 않습니다?

의 모든 값 유형에

을 적용 이제

int i = SomeFunctionThatReturnsInt(); 

if(i == null) //compiler exception here 

을 (닷넷 2 또는 3.5) 예외가 사라졌습니다. 이 이유

내가 알고

int? j = null; //nullable int 

if(i == j) //this shouldn't throw an exception 

문제는 int?이 널 (NULL) 입력 가능하고 int 때문에 지금 int?에 대한 암시 적 캐스트를 가지고 있다는 것입니다. 위 구문은 컴파일러 마술입니다. 정말 우리가하고있는 우리가 i == null을 수행 할 때

Nullable<int> j = null; //nullable int 

//compiler is smart enough to do this 
if((Nullable<int>) i == j) 

//and not this 
if(i == (int) j) 

을 그래서 지금, 우리가 얻을 : C#을 어쨌든이를 계산하는 이유가 충분히 영리하지 않을 수 컴파일러 로직을하고있다

if((Nullable<int>) i == null) 

주어진 null과 같은 절대 값을 처리 할 때 그러지 않습니까?

답변

3

나는 이것이 컴파일러 문제라고 생각하지 않는다. 그 자체로; 정수 값은 결코 null이 아니지만, 이들을 동일시한다는 생각은 유효하지 않습니다. 항상 false를 반환하는 유효한 함수입니다. 그리고 컴파일러는 알고 있습니다. 코드

bool oneIsNull = 1 == null; 

컴파일,하지만 컴파일러 경고를 제공합니다 The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type '<null>'.

컴파일러 오류를 다시 되돌리려면 프로젝트 속성으로 이동하여이 오류에 대한 '경고를 오류로 처리'를 설정하면 다시 빌드 문제로 간주되기 시작합니다.

1

Null이 허용되지 않는 형식을 Null과 비교할 때 컴파일러에서 여전히 경고를 생성합니다. 이는 해당 형식이어야합니다. 5 월 귀하의 경고 수준이 너무 낮습니다 또는이 최근 버전에서 변경되었습니다 (나는 그 .net 3.5 않았다).

3

이상한 ... 표적으로, VS2008와 함께이 컴파일 .NET 3.5 :

static int F() 
    { 
     return 42; 
    } 

    static void Main(string[] args) 
    { 
     int i = F(); 

     if (i == null) 
     { 
     } 
    } 

내가

warning CS0472: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'int?' 

경고 컴파일러를 얻을 그리고 그것은 ... 어떤 아마도 JIT를 다음 IL를 생성 멀리 낙관 할 것입니다

L_0001: call int32 ConsoleApplication1.Program::F() 
    L_0006: stloc.0 
    L_0007: ldc.i4.0 
    L_0008: ldc.i4.0 
    L_0009: ceq 
    L_000b: stloc.1 
    L_000c: br.s L_000e 

코드 스 니펫을 게시 할 수 있습니까?

+0

컴파일러는 정확히 1 == 2 일 때와 똑같이 사실이 아님을 정확히 나타냅니다. int가 암시 적으로 int로 캐스팅 될 수 있다는 것을 알면 충분히 똑똑합니까? 그 int? null와 비교할 수 있습니다. 최적화 도구가 전체 블록을 제거 할만큼 똑똑하다고 생각합니다. – Keith

0

경고가 새 것입니다. (3.5 생각합니다) - 오류는 내가 수행 한 것과 똑같습니다. 1 == 2은 결코 사실이 아니므로 현명한 것입니다.

전체 3.5 최적화로 전체 진술이 제거 될 것이라고 생각합니다. 실제 평가가 없으면 꽤 똑똑하기 때문입니다.

1==2 (예 : 다른 것을 테스트하는 동안 기능 블록을 끄기 위해)을 컴파일하는 동안 나는 1==null을 원하지 않을 수 있습니다.

0

형식이 호환되지 않기 때문에 (값 형식을 절대 null 일 수 없음) 컴파일 타임 오류가 발생해야합니다. 그것은 꽤 슬프다.

+0

전체적인 질문을 읽고, 왜 그것이 발생하는지 설명합니다. 문제는 특별한 경우로 취급 될 수없는 이유입니다. – Keith

+0

내가 "해야한다"고 말하면 나는 도덕적 명령이 있다는 것을 의미한다. 그것이 내가 컴파일러가 기대하는 것이 아니다. 당신이 설명하는 이론적 근거는 그다지 매력적이지 않습니다. 그들은 정적 컴파일 실패로 만들어야합니다. – DrPizza

1

2.0 프레임 워크는 nullable 값 유형을 도입했습니다. 리터럴 상수 "1"이 결코 null이 될 수는 없지만, 그 기본 유형 (int)은 이제 Nullable int 유형으로 형변환 될 수 있습니다. 내 생각 엔 컴파일러가 int 타입이 nullable이 아니라고 가정 할 수 없다는 것입니다.

경고 1 'int'유형의 값이 'int'유형의 'null'과 결코 같지 않으므로 표현식의 결과는 항상 '거짓'입니다.

+0

내가 말했듯이 컴파일러는 int가 암시 적으로 int로 캐스팅 될 수 있다는 것을 알고 있습니까? int? null와 비교할 수 있습니다. 경고는 절대로 비교할 수없는 일반적인 경고입니다. 1 == 2는 같은 경고를 던집니다. – Keith

관련 문제