2016-09-24 2 views
0

환경 : 비주얼 스튜디오 2015널 조건 연산자

시간대 : : UTC + 7시, 방콕

문제 : DateTimeOffset으로 널 (NULL) varialbe에 (?을 DateTimeOffset)의 조건부 연산자를 사용하면 예외가 발생합니다. 즉, 값이 NULL (DateTimeOffset? 값) 인 경우에도 여전히 메서드를 호출합니다. ToLocalTime()은 ToLocalTime을 호출하고 예외를 발생시킵니다.

쿼리 :이 UTC 잘 작동 내가 널 조건 연산자를 사용하거나 연산자 대신 GetValueOrDefault를 사용하지 않음으로써 그것을 해결할 수 있지만 그것이 모든 UTC +에서 시간대 예외 resutls 이유를 이해하려면 - TimeZone이를

코드 :

var dateTimeMinimum = DateTime.MinValue; 
    var value = (object)dateTimeMinimum; // Mimic the WPF converter behavior 
    var a1 = value as DateTimeOffset?; // This works 
    if (a1 != null)// This works as it won't execute the code in the 'if'loop 
    { 
     var b1 = (a1 as DateTimeOffset?)?.ToLocalTime(); 
    } 

var dto = (value as DateTimeOffset?)?.ToLocalTime() ?? (DateTime)value;// This breaks with following exception 

enter image description here

편집 : 내가 뭔가를하지 않는 널 조건 연산자

var a1 = value as DateTimeOffset?; 

를 사용하지 않는 내가 코드 즉

DateTime dateTimeMinimum = DateTime.SpecifyKind(DateTime.MinValue, DateTimeKind.Utc); 

여기 내 쿼리가 생각의 문제를 해결하는 방법에는 여러 가지가 이해

, 예외가 발생합니다. 널 조건 연산자는 당 변수를 펼쳤다 때문인가요 블로그 다음

http://www.ninjacrab.com/2016/09/11/c-how-the-null-conditional-operator-works-with-nullable-types/

나는 간단한 캐스팅 '으로'연산자를 사용하는 경우 때 내가 널 조건 연산자를 사용하면 고장 및 작동 이유를 이해하는데 더 관심 DateTimeKind.Utc

EDIT2을 사용하지 않고 :

이 DateTimeOffset으로 (.NET 프레임 워크 코드)의 생성자이며 ValidateOffset 방법에 나옵니다. 소스-http://referencesource.microsoft.com/#mscorlib/system/datetimeoffset.cs,68b4bb83ce8d1c31

// Constructs a DateTimeOffset from a DateTime. For Local and Unspecified kinds, 
     // extracts the local offset. For UTC, creates a UTC instance with a zero offset. 
     public DateTimeOffset(DateTime dateTime) { 
      TimeSpan offset; 
      if (dateTime.Kind != DateTimeKind.Utc) { 
       // Local and Unspecified are both treated as Local 
       offset = TimeZoneInfo.GetLocalUtcOffset(dateTime, TimeZoneInfoOptions.NoThrowOnInvalidTime); 
      } 
      else {    
       offset = new TimeSpan(0); 
      } 
      m_offsetMinutes = ValidateOffset(offset); 
      m_dateTime = ValidateDate(dateTime, offset); 
     } 
+0

해당 예외가 발생했을 때의 오프셋 값은 무엇입니까? 오류 메시지는 결과 연도가 0보다 작거나 10K보다 큼을 제안하는 것 같습니다 – pquest

+0

DateTime.MinValue –

+0

오프셋 값입니까? – pquest

답변

1

문제는 최소 날짜는 UTC 0 점이다, 그래서 당신이 원하는 경우에 그 하지만 UTC 0이 가능한 최소 DateTime 이전된다는 것을 의미합니다 긍정적 인 UTC와.

은 간단히 말해,이 (최소 날짜 UTC의 일을) 만들 수 없습니다 :

new DateTimeOffset(DateTime.MinValue, new TimeSpan(1, 0, 0)) 

을이 12 월 31 일 -0001 오후 11:00 UTC에 대한 DateTimeOffset을 만들 것입니다 때문입니다. 예외가 발생하는 경우입니다 다음 dto으로

var dto = <something null> ?? (DateTime)value; 

가, 거기에 당신이 (DateTimeOffset)(DateTime)value을하고, DateTimeOffset로 추정되고 :

예외가 바로 여기에 발생합니다. 그 캐스트는 표현할 수없는 부정 날짜를 만들려고합니다.

var dateTimeMinimum = DateTime.MinValue; 
var value = (object)dateTimeMinimum; // Mimic the WPF converter behavior 
DateTimeOffset dto = (DateTime)value; 

UPDATE

당신은 여전히 ​​저를 믿지 않는,이 시도 :

문제가 널 변수에을 관련이없는 것을 확인하기 위해이 코드를 사용해보십시오 :

var dto = (value as DateTimeOffset?)?.ToLocalTime() ?? new DateTimeOffset(); 

이 작업은 실패하지 않습니다. 왜? ToLocalTime이 아니기 때문에 실행되지 않고이 아니며이 시간에 실패한 것은 내가 말한 것입니다. 최소값은 DateTime에서 DateTimeOffset이고 양수 시간대입니다.


BTW, 당신은 단지 as 운영자와 DateTimeOffset?DateTime을 변환 할 수 없습니다; 항상 null이 리턴됩니다. 이 연산자는 호환되는 클립 용입니다.

결국이 문제를 해결하더라도 코드를 이해하고 유지하기가 너무 어렵다고 생각합니다. 정확히 여기서 뭘 하려구?

+0

내가 NULL 값을 원하고 null 조건부 연산자를 사용하고있다. 그것이 Null 인 경우 DateTime으로 구문 분석하려고합니다. –

+0

var dto = (DateTimeOffset? 값)? ToLocalTime() ?? (DateTime) 값; –

+0

하지만 null이 아니므로 예외가 발생합니다 ... UTC LocalTime (UTC +7)로 변환 된 최소 DateTime이 해당 예외를 throw합니다. null 관련 문제가 없습니다. – Andrew

0

이가 널 (NULL) 연산자와는 아무 상관이있다.

var dto2 = new DateTimeOffset(dateTimeMinimum); 

당신이 DateTime.Now로 변경하는 경우, DateTime.Min를 사용하는 경우 오프셋이 너무 커서, 코드가 작동합니다

같은 오류가 발생합니다.

+0

응답 해 주셔서 감사합니다. 내 코드에 a1 변수가 있으면 NULL 값이되고 블록이면 실행되지 않습니다. 같은 방식으로 "value"변수가 DateTimeOffset?으로 형 변환되면 NULL이어야하며 예외가 발생해서는 안됩니다. –

+0

NULL 연산자가 값을 얻으려고 시도하는 동안 관련이없는 클래스 인 DateTime과 DateTimeOffset간에 변환하려고하므로이 경우 as 연산자는 항상 NULL을 반환합니다. 나는 Roslyn null 연산자의 "배후"에 익숙하지 않다. 그러나 나는 당신의 라인이 명시 적 캐스트처럼 동작한다고 믿는다. –