【问题标题】:Cannot implicitly convert 'System.TimeSpan?' to 'System.TimeSpan'无法隐式转换“System.TimeSpan?”到'System.TimeSpan'
【发布时间】:2016-07-23 12:28:53
【问题描述】:

以下代码运行良好:

DateTime d1 = DateTime.Now;
DateTime d2 = DateTime.Now.AddDays(-1);
int d3 = (int)(d1 - d2).TotalDays;

但是如果我将DateTime 定义为DateTime? 会怎样:

DateTime? d1 = DateTime.Now;
DateTime? d2 = DateTime.Now.AddDays(-1);
int d3 = (int)(d1 - d2).TotalDays;

红色下划线错误

无法隐式转换“System.TimeSpan?”到'System.TimeSpan'

是否可以获得定义为可为空的两个日期时间之间的天数差异?

【问题讨论】:

  • int d3 = (int)(d1.Value - d2.Value).TotalDays;

标签: c# datetime asp.net-mvc-5 timespan


【解决方案1】:

是的,但是您需要使用Value 属性来“取消”它:

int d3 = (int)(d1 - d2).Value.TotalDays;

但是,您应该考虑 d1d2 为 null 的可能性 - 在您的情况下不会发生这种情况,但在其他情况下可能会发生。你可能想要:

int? d3 = (int?) (d1 - d2)?.TotalDays;

如果d1d2null,这将给出null 的结果。当然,这是假设您使用的是 C# 6 - 否则 ?. 运算符不可用。

(您可以按照 user3185569 的建议在第一种情况下使用 GetValueOrDefault(),但如果其中一个值为 null,那么它会默默地使用空的 TimeSpan,感觉不太可能是您想要的。)

【讨论】:

  • GetValueOrDefault() 的使用是对给定代码的合理优化,适用于已知可为 null 不为 null 的其他情况(通常是在精确地测试分支时),但是像所有优化一样,知道何时不使用它比知道它提供的微选项更重要。
【解决方案2】:

是的,使用GetValueOrDefault()

DateTime? d1 = DateTime.Now;
DateTime? d2 = DateTime.Now.AddDays(-1);
int d3 = (int)(d1 - d2).GetValueOrDefault().TotalDays;

d1 - d2 返回 Nullable TimeSpan,它不直接包含名为 TotalDays 的属性。但是使用GetValueOrDefault(),您可以返回一个TimeSpan 对象,如果值为NULL,则获得0 Total Days

如果您确实期望Null 值,最好区分0 天(上述方法返回的内容)和无效操作(日期-空)、(空-日期)和(空-空)。那么您可能需要使用另一种方法:

int? d3 = (int) (d1 - d2)?.TotalDays;

或者,如果您使用的是 C# 6 之前的版本:

int? d3 = d1.HasValue && d2.HasValue ? (int)(d1 - d2).Value.TotalDays : new int?();

【讨论】:

  • 这是一种简洁的代码,但 OP 必须理解 null - null = 0 这可能不是真的。如果null - null = null 可能会更好。
  • @Enigmativity 你是对的。但我从 OP 了解到的是日期是有效的,但只是定义为Nullable。否则,区分 0 天差异和无效操作是非常有意义的。
【解决方案3】:

使用 long 并转换

long x
System.TimeSpan y= new TimeSpan(x);

【讨论】:

    猜你喜欢
    • 2017-05-08
    • 2015-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-05
    • 2015-10-12
    • 2013-02-22
    • 2017-05-25
    相关资源
    最近更新 更多