Nullable <int>를 증가 시키면 예외가 발생하지 않는 이유는 무엇입니까?


98

Console.WriteLine이 왜 빈 줄을 작성하고 ( Console.WriteLine(null)컴파일 오류가 발생 a+=1합니까) NullReferenceException이없는 이유 (심지어 발생 해서는 안 됨 )를 설명해 주 시겠습니까?

int? a = null;
a++; // Why there is not NullReferenceException? 
Console.WriteLine(a); // Empty line

모든 세 개의 연산자 ++, +=+변형을 해제했다. 따라서 문은 a++;, a += 1;그리고 a = a + 1;모두 사용할 수 있습니다. 초기에 각 생산물 null(예외 발생 없음) . anull
Jeppe Stig Nielsen

5
NullReferenceException? 하지만 int?하지 않은 것입니다 Reference그것은 단지입니다, int취할 수있는 null값을
Khaled.K

답변:


124

당신은 들어 올린 작업자 의 효과를 관찰하고 있습니다 .

C # 5 사양의 섹션 7.3.7에서 :

리프트 연산자를 사용하면 nullable이 아닌 값 형식에서 작동하는 미리 정의 된 사용자 정의 연산자를 이러한 형식의 nullable 형식과 함께 사용할 수도 있습니다. 리프팅 연산자는 다음과 같이 특정 요구 사항을 충족하는 사전 정의 및 사용자 정의 연산자로 구성됩니다.

  • 단항 연산자 + ++ - -- ! ~ 의 경우 피연산자와 결과 형식이 모두 nullable이 아닌 값 형식이면 리프트 형식의 연산자가 존재합니다. 해제 된 양식은 ?피연산자 및 결과 유형에 단일 수정자를 추가하여 구성됩니다 . 리프트 연산자는 피연산자가 null이면 null 값을 생성합니다. 그렇지 않으면 리프트 된 연산자가 피연산자를 풀고 기본 연산자를 적용한 다음 결과를 래핑합니다.

따라서 기본적 a++으로이 경우 결과는 null( )의 표현식이며 int?변수는 그대로 유지됩니다.

전화 할 때

Console.WriteLine(a);

그것은 boxing되고 object있으며, null 참조로 변환되어 빈 줄로 인쇄됩니다.


3
사용하지 않고 "null"을 인쇄하는 방법이 Console.WriteLine(a == null ? "null" : a)있습니까?
Cole Johnson

5
@Cole Johnson : Console.WriteLine (a ?? "null"); :)
David Chappelle

2
때 @DavidChappelle는 a타입이다 int?, 나는 말할 것입니다 a ?? "null"발견에게 두 피연산자에 대한 일반적인 유형입니다. object일반적인 유형 인 힌트가 필요합니다 . 따라서 피연산자 중 하나를 그것에 캐스팅하십시오. 은 a박스 될 것입니다. 예를 들어 ((object)a) ?? "null"또는 a ?? (object)"null".
Jeppe Stig Nielsen

감독자. 사양에 연결할 수 있습니까? 자체 클래스에서 연산자를 오버로드 할 때 이것을 정의 할 수 있습니까?
Phil

@teabaggs : 지금은 쉽게 연결할 수 없으며 링크는 Word 문서 (검색으로 쉽게 찾을 수 있음)로 연결됩니다. 적절한 경우 연산자 과부하를 정의 할 때 자동으로 리프팅 된 연산자를 얻습니다.
Jon Skeet 2015 년

116

Jon의 대답은 정확하지만 몇 가지 추가 메모를 추가합니다.

Console.WriteLine(null)컴파일 오류가 발생합니까?

19 개의 과부하가 Console.WriteLine있으며 그 중 3 개는 a에 적용 할 수 있습니다 null: a 를 취하는 것 string, a를 취하는 것 , a char[]를 취하는 것 object. C #은이 세 가지 중 무엇을 의미하는지 확인할 수 없으므로 오류가 발생합니다. Console.WriteLine((object)null)이제는 명확하기 때문에 합법적입니다.

Console.WriteLine(a)빈 줄을 쓰나요?

anull int?입니다. 오버로드 확인은 object메서드 의 버전을 선택 int?하므로은 null 참조로 박스됩니다. 따라서 이것은 기본적으로 Console.WriteLine((object)null)빈 줄을 쓰는와 동일 합니다.

NullReferenceException증분 이없는 이유는 무엇 입니까?

걱정 되는 널 참조 는 어디에 있습니까 ? 시작할 참조 유형이 아닌 anull int?입니다! nullable 값 유형은 참조 유형이 아니라 값 유형 이므로 참조 유형 에 대해 boxing되지 않는 한 참조 의미 체계를 가질 것으로 기대하지 마십시오. 추가로 권투가 없습니다.


0

널 증가하고 있습니까 ???

int? a = null;
a++;

이 문장은 단순히 null++null + 1을 의미 합니다.

이 문서에 따라 nullable 형식은 기본 값 형식에 대한 올바른 값 범위와 추가 null 값을 나타낼 수 있습니다. Nullable ( "Int32의 Nullable"이라고 발음)에는 -2147483648에서 2147483647까지의 모든 값을 할당 할 수 있습니다. null 값을 할당 할 수 있습니다.

여기에서 null을 증가 시키면 0이나 다른 정수가 아닌 null 값이됩니다.

왜 오류 대신 공백으로 인쇄됩니까 ??

null 값으로 nullable 유형을 인쇄하면 변수, 즉 메모리 위치의 값을 인쇄하기 때문에 오류 대신 공백이 인쇄됩니다. null 또는 정수일 수 있습니다.

그러나 null을 사용하여 인쇄하려고 할 때 Console.WriteLine(null)null은 변수가 아니므로 메모리 위치를 참조하지 않습니다. 따라서 오류가 발생 "NullReferenceException"합니다.

그런 다음 Console.WriteLine(2);??를 사용하여 정수를 어떻게 인쇄 할 수 있습니까 ?

이 경우 2는 임시 위치에서 메모리에 저장되고 포인터는 인쇄 할 해당 메모리 위치를 가리 킵니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.