?의 nullable 형식 문제 : 조건부 연산자


154

누군가 이것이 C # .NET 2.0에서 작동하는 이유를 설명 할 수 있습니까?

    Nullable<DateTime> foo;
    if (true)
        foo = null;
    else
        foo = new DateTime(0);

...하지만 그렇지 않습니다 :

    Nullable<DateTime> foo;
    foo = true ? null : new DateTime(0);

후자의 형식은 " 'null>'과 'System.DateTime'사이에 암시 적 변환이 없기 때문에 조건식의 유형을 확인할 수 없습니다."라는 컴파일 오류를 나타냅니다.

전자를 사용할 수는 없지만 두 번째 스타일은 나머지 코드와 더 일관성이 있습니다.


12
DateTime을 사용하여 타이핑을 많이 절약 할 수 있습니까? Nullable <DateTime> 대신.
스튜어트 존슨

답변:


325

이 질문은 이미 여러 번 요청되었습니다. 컴파일러는 어떻게 변환 모르는 당신을 말하고있다 null로를 DateTime.

해결책은 간단합니다.

DateTime? foo;
foo = true ? (DateTime?)null : new DateTime(0);

참고 Nullable<DateTime>쓸 수있는 DateTime?당신에게 입력의 무리를 저장합니다.


잘 작동하지만 이제는 foo를 null 검사 할 수 없습니다. 항상 값을 갖습니다. MojoFilter는 "삼항 연산자에서 두 값이 같은 유형이어야하기 때문"이라고 말합니다.
DilbertDave

@DilbertDave MojoFilter의 게시물 정보가 올바르지 않습니다.
Mishax

4
컴파일러는 할당 된 변수를 보지 않고 대신 피연산자를보고 삼항 연산의 결과 유형을 추측하려고합니다. 그것은 발견 <null>하고 DateTime대신 공통 조상 유형을 찾는, 그냥 서로 간의 변환을 찾으려고합니다. (추가 비트 : C #은 <null>유형, 즉 모든 null표현식 의 유형을 인식합니다 .)
IllidanS4는 Monica를

이미 여러 번 질문을 받았다면 중복 질문 플래그는 어디에 있습니까?
starmandeluxe

여기에 그들은 모든 가능성이 점을 @starmandeluxe (적어도 나는 내가 어떻게 왔는지 있음)
스콧 체임벌린

19

FYI (주제이지만 깔끔하고 nullable 유형과 관련 있음) null 병합 연산자라는 nullable 유형에 대한 편리한 연산자가 있습니다.

??

이런 식으로 사용 :

// Left hand is the nullable type, righthand is default if the type is null.
Nullable<DateTime> foo;
DateTime value = foo ?? new DateTime(0);

9
이것이 그의 질문에 어떻게 대답합니까?
스튜어트 존슨

3
Nick은 일부 조건이 true 인 경우 foo에 널을 지정하려고합니다. foo가 null 인 경우 null 통합은 DateTime (0)을 값에 할당합니다. 두 사람은 완전히 관련이 없습니다.
Jeromy Irvine

4
따라서 FYI, 주제는 아니지만 좋은 것입니다.
FlySwat

그래. 아는 것이 매우 유용합니다.
Jeromy Irvine

8

삼항 연산자에서는 두 값이 동일한 유형으로 해석되어야하기 때문입니다.


10
아니요, 같은 유형일 필요는 없습니다. 두 번째 피연산자는 암시 적으로 세 번째 피연산자의 유형으로 또는 다른 방법으로 변환 가능해야합니다.
Mishax

3

이 질문이 2008 년에 요청되었으며 5 년이 지난 지금도 답변으로 표시된 답변이 만족스럽지 않습니다. 진정한 대답은 DateTime이 구조체이며 구조체로 null과 호환되지 않는다는 것입니다. 이를 해결하는 두 가지 방법이 있습니다.

첫 번째는 null을 DateTime과 호환 가능하게 만드는 것입니다 (예를 들어 70 개의 공감 율이있는 신사가 제안한대로 null을 DateTime?으로 캐스팅하거나 Object 또는 ValueType으로 null을 캐스팅).

두 번째는 DateTime을 null과 호환 가능하게 만드는 것입니다 (예 : DateTime을 DateTime으로 캐스트?).


3

허용되는 것과 비슷한 또 다른 솔루션은 C #의 default키워드를 사용하는 것입니다. 제네릭을 사용하여 정의되었지만 실제로는 모든 유형에 적용 할 수 있습니다.

OP의 질문에 적용된 사용 예 :

Nullable<DateTime> foo;
foo = true ? default(DateTime) : new DateTime(0);

현재 허용되는 답변의 사용법 예 :

DateTime? foo;
foo = true ? default(DateTime) : new DateTime(0);

또한을 사용하여 값 을 할당하기 위해 default변수를 지정할 필요가 없습니다 . 컴파일러는 특정 변수 유형의 기본값을 자동으로 할당하며 오류가 발생하지 않습니다. 예:nullablenull

DateTime foo;
foo = true ? default(DateTime) : new DateTime(0);

13
true default(DateTime)가 아닌 경우 null이 아니며 " 1.1.0001 0:00:00"과 동일합니다 new DateTime(0).
IllidanS4가 Monica를

@ IllidanS4, 나는 그것이 동등하다고 말하지 않았으며 null, 오직 default()당신이 그것을 사용하여 nullable값을 (MSDN 상태로) 할당 할 수 있다고 말하지 않았습니다 . 내가 보여주는 예 Nullable<DateTime>DateTime?, 및 간단하게 사용할 수있는 다양성을 보여줍니다 DateTime. 이것이 잘못되었다고 생각되면, 이것이 실패한 PoC를 제공 할 수 있습니까?
newfurniturey

3
음, 질문자는 null변수가 아닌 변수 에 저장하기를 원했기 default(DateTime)때문에 이것이 잘못되었습니다. 당신이 의미로 전체 표현식이 여전히 같은 유형이 있기 때문에 이것은, "다양한"아닙니다 - DateTime, 당신은 대체 할 수 default(DateTime)와 함께 new DateTime()하고 같은 일을 할 것입니다. 어쩌면 default(DateTime?)당신이 의미하는 것일 수도 있습니다. 왜냐하면 실제로는와 같습니다 null.
IllidanS4가 Monica를
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.