环境: Visual Studio 2015
TimeZone::UTC + 7:00,曼谷
问题:在DateTimeOffset可以为空的varialbe(DateTimeOffset?)上,使用Null Conditional运算符会导致异常,即即使值为NULL,它仍会调用该方法,即(值为DateTimeOffset?)? .ToLocalTime(),它调用ToLocalTime并导致异常。
查询:我可以通过不使用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);
这是我的查询,当我不使用空条件运算符
时var a1 = value as DateTimeOffset?;
不会导致异常。是因为null条件运算符会在每个后续博客
中展开变量http://www.ninjacrab.com/2016/09/11/c-how-the-null-conditional-operator-works-with-nullable-types/
我更感兴趣的是理解为什么它在我使用null条件运算符时会中断,并且当我使用' as'运算符而不使用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 :(得分:1)
问题是最小日期是UTC 0,所以如果你想要那个但是具有正的UTC ,这意味着在UTC 0它将早于最小可能{{1 }}
简单地说,你不能创建它(最小日期UTC +1):
DateTime
因为这会在12月31日 -0001 11:00 PM UTC创建new DateTimeOffset(DateTime.MinValue, new TimeSpan(1, 0, 0))
。
异常发生在这里:
DateTimeOffset
当var dto = <something null> ?? (DateTime)value;
被推断为dto
时,您正在执行DateTimeOffset
,然后是抛出异常的时间。该演员试图创建负日期,无法表示。
尝试使用此代码确认问题
(DateTimeOffset)(DateTime)value
<强>更新强>
你仍然不相信我,试试这个:
var dateTimeMinimum = DateTime.MinValue;
var value = (object)dateTimeMinimum; // Mimic the WPF converter behavior
DateTimeOffset dto = (DateTime)value;
这不会失败。为什么?因为var dto = (value as DateTimeOffset?)?.ToLocalTime() ?? new DateTimeOffset();
没有被执行而且永远不会,而且我所说的一直失败的是从最小ToLocalTime
到DateTime
的演员阵容时区。
顺便说一句,您不能只使用DateTimeOffset
运算符将DateTime
转换为DateTimeOffset?
;总是会返回null。该运算符用于兼容的clases。
最后,即使解决这个问题,我认为您的代码也很难理解和维护。你到底想干什么?
答案 1 :(得分:0)
这与可空操作符无关。
这会导致同样的错误:
var dto2 = new DateTimeOffset(dateTimeMinimum);
使用DateTime.Min时偏移量太大,如果将其更改为DateTime.Now,则代码将起作用。