如何使用具有可空日期的null-coalescing运算符

时间:2016-11-24 13:09:46

标签: c# asp.net-mvc datetime asp.net-core nullable

我的视图模型具有可以为空的日期属性,例如......

[DataType(DataType.Date)]
public DateTime? SanctionExpires { get; set; }

但是当我尝试使用null-coalescing运算符时,例如......

var test = model.SanctionExpires.Value.ToUniversalTime() ?? model.SanctionExpires;

我收到以下错误...

  

运营商'??'不能应用于'datetime'类型的操作数   '日期时间'

我认为这应该有效,因为我将我的日期属性设置为可空,this post表明它应该也可以。我做错了什么?

更新

为了更清晰,我想使用null-coaslescing来分配一个Dapper参数,该参数将更新数据库中的DateTime字段。该字段可以接受空值或日期时间值。基本上,如果用户指定日期,则将提供的日期分配给参数,否则指定null ...

p.Add("@SanctionExpires", model.SanctionExpires.Value.ToUniversalTime() ?? model.SanctionExpires);

请注意,我必须进行UTC转换,因为我使用的是使用UTC作为日期的SQL Azure,否则如果我只是从本地系统传递数据,那么我的时间将超过11小时(我在澳大利亚)。在sql中我使用函数在更新表之前将日期偏移到我的时区。

我目前的解决方案是让它工作,但不确定这是否是最干净的方法。能够排成一行真是太好了......

if (model.SanctionExpires == null)
    p.Add("@SanctionExpires", model.SanctionExpires);
else
    p.Add("@SanctionExpires", model.SanctionExpires.Value.ToUniversalTime());

2 个答案:

答案 0 :(得分:11)

可空的

.Value假设它不能为空。因此,对它使用null-coalescing运算符是无用的和禁止的。

您可以像这样使用运算符,但是继续使用您的代码我不确定这是否是您需要的:

DateTime test = (model.SanctionExpires ?? DateTime.Now).ToUniversalTime();

对于您的更新:您可以像这样简化评估:

DateTime? test = model.SanctionExpires?.ToUniversalTime();

答案 1 :(得分:0)

如果DateTime对象为null,您还可以使用GetValueOrDefault方法返回默认值。如果您想使用实际日期,则应使用DateTime.Now

例如,以下代码段可以帮助您:

var defaultDateTime = DateTime.Now;
var dateTime = model.SanctionExpires.GetValueOrDefault(defaultDateTime).ToUniversalTime();

如果您在没有参数的情况下致电GetValueOrDefault,如果您的日期时间为空,则会使用default(DateTime)

var dateTime = model.SanctionExpires.GetValueOrDefault().ToUniversalTime(); //dateTime == default(DateTime) in case !model.SanctionExpires.HasValue

<强>更新

如果您使用的是C#5.0或更低版本,则可以使用以下代码段,因为NULL conditional operator在C#6.0之前不可用。

p.Add("@SanctionExpires", !model.SanctionExpires.HasValue ? null : (DateTime?)model.SanctionExpires.Value.ToUniversalTime());