環境: Visual Studio 2015
TimeZone: : UTC + 7:00、バンコク
問題: DateTimeOffset の null 許容変数 (DateTimeOffset?) で、Null 条件付き演算子を使用すると例外が発生します。つまり、値が NULL の場合でもメソッドが呼び出されます。例外が発生します。
クエリ: Null 条件演算子を使用しないか、演算子の代わりに GetValueOrDefault を使用することで解決できますが、すべての UTC + TimeZones で例外が発生する理由を理解したいのですが、UTC - TimeZones でうまく機能します
コード:
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
編集:
コードを修正するには多くの方法があることを理解しています。
DateTime dateTimeMinimum = DateTime.SpecifyKind(DateTime.MinValue, DateTimeKind.Utc);
ただし、null 条件演算子を使用しない場合のクエリは次のとおりです。
var a1 = value as DateTimeOffset?;
例外にはなりません。以下のブログごとに、null 条件演算子が変数をアンラップするためでしょうか
http://www.ninjacrab.com/2016/09/11/c-how-the-null-conditional-operator-works-with-nullable-types/
null条件演算子を使用すると壊れ、DateTimeKind.Utcを使用せずに「as」演算子を使用すると単純なキャストで機能する理由を理解することにもっと興味があります。
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);
}