.Net 2+:if( 1 == null )이 더 이상 컴파일러 예외를 발생시키지 않는 이유는 무엇입니까?

StackOverflow https://stackoverflow.com/questions/62606

문제

나는 사용하고있다 int 예를 들어 이는 .Net의 모든 값 유형에 적용됩니다.

.Net 1에서는 다음이 컴파일러 예외를 발생시킵니다.

int i = SomeFunctionThatReturnsInt();

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

이제 (.Net 2 또는 3.5에서) 해당 예외가 사라졌습니다.

나는 이것이 왜인지 압니다:

int? j = null; //nullable int

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

문제는 그렇기 때문에 int? nullable이고 int 이제 암시적 캐스트가 있습니다. int?.위의 구문은 컴파일러 마법입니다.실제로 우리는 다음을 수행하고 있습니다.

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)

그럼 이제 우리가 할 때 i == null 우리는 다음을 얻습니다:

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

어쨌든 C#이 이를 계산하기 위해 컴파일러 논리를 수행하고 있다는 점을 고려하면 다음과 같은 절대값을 처리할 때 이를 수행하지 않을 만큼 똑똑할 수 없는 이유는 무엇입니까? null?

도움이 되었습니까?

해결책

이건 컴파일러 문제가 아닌거 같은데 그 자체로;정수 값은 결코 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>'.

따라서 컴파일러 오류를 다시 확인하려면 프로젝트 속성으로 이동하여 이 오류에 대해 '경고를 오류로 처리'를 설정하세요. 그러면 다시 빌드 중단 문제로 표시되기 시작합니다.

다른 팁

이상한 ....NET 3.5를 대상으로 VS2008로 이것을 컴파일:

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?'

그리고 다음 IL을 생성합니다.아마도 JIT는 최적화할 것입니다.

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

코드 조각을 게시할 수 있나요?

컴파일러는 null을 허용하지 않는 유형을 null과 비교할 때 여전히 경고를 생성합니다. 이는 당연히 그래야 하는 방식입니다.경고 수준이 너무 낮거나 최근 버전에서 변경되었을 수 있습니다(.net 3.5에서만 해당).

2.0 프레임워크에서는 nullable 값 유형을 도입했습니다.리터럴 상수 "1"은 null이 될 수 없지만 이제 기본 유형(int)을 Nullable int 유형으로 캐스팅할 수 있습니다.내 생각엔 컴파일러가 더 이상 int 유형이 리터럴 상수인 경우에도 null을 허용하지 않는다고 가정할 수 없다는 것입니다.2.0을 컴파일할 때 경고가 나타납니다.

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

경고는 새로운 것입니다(제 생각에는 3.5입니다). 오류는 제가 한 것과 동일합니다. 1 == 2, 결코 사실이 아닌 것을 발견할 만큼 똑똑합니다.

나는 완전한 3.5 최적화를 사용하면 전체 진술이 제거될 것이라고 생각합니다. 이는 결코 진정한 평가가 아닌 매우 영리하기 때문입니다.

내가 원할 수도 있지만 1==2 컴파일하다 (예를 들어 다른 것을 테스트하는 동안 기능 블록을 끄기 위해) 원하지 않습니다 1==null 에게.

유형이 호환되지 않기 때문에(값 유형은 null이 될 수 없음) 컴파일 시간 오류여야 합니다.그렇지 않은 것이 참 안타깝습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top