System.DateTime? vs System.DateTime

31

我正在编写一些代码,需要从我的页面上的日历控件(Ajax工具包:日历扩展程序)中读取日期值。

以下是代码:

DateTime newSelectedDate = myCalendarExtender.SelectedDate;
给出以下错误:
Cannot implicitly convert type 'System.DateTime?' to 'System.DateTime'. An explicit conversion exists (are you missing a cast?)

然而,通过插入一个强制类型转换,我可以使代码正常工作:

DateTime newSelectedDate = (DateTime)myCalendarExtender.SelectedDate; // works fine!

Ajax工具包中日历控件的“SelectedDate”属性将数据类型描述为“System.DateTime?”...很明显'?'与此有关。

当数据类型包含此符号(?)时会发生什么……我假设我可以直接将“SelectedDate”属性应用于类型为“DateTime”的变量中而无需强制转换。

谢谢

6个回答

49

?表示该类型可以为空。有关详细信息,请参见例如MSDN

Nullable是编译器支持的一个值类型的包装器,它允许值类型变为null。

要访问DateTime值,您需要执行以下操作:

DateTime? dateOrNull = myCalendarExtender.SelectedDate;
if (dateOrNull != null)
{
    DateTime newSelectedDate = dateOrNull.Value;
}

@Marek - 你更喜欢原始URL吗?那我对编辑的行为感到抱歉。 - Jeff Sternal
@Jeff:他也在他的编辑中添加了代码块,所以这很可能不是故意更改......只是他在你的编辑之前已经打开了编辑屏幕。 - Powerlord
@Jeff:抱歉,这是无意的。我不知道你编辑了URL,我的编辑覆盖了你的。 - Marek
呼,我不确定那种事情是否有失礼了。:D - Jeff Sternal
感谢所有回复的人,现在一切都更加清晰明了! :) - Dalbir Singh
顺便提一下,现在在VB.NET中也是有效的。我们现在不必再写Dim SomeCrap as Nullable(Of Integer),只需写Dim SomeCrap as Integer?即可。 - Chase Florell

24

DateTime?Nullable<DateTime>相同。即:DateTime?的实例可以包含“NULL”,而DateTime的实例不包含。
(.NET 2.0以后所有值类型都是如此。值类型不能包含NULL,但是从.NET 2.0开始,通过Nullable<T>结构(或?缩写)支持可空值类型。)

您可以通过以下方式获取DateTime?的值并将其放入DateTime中:

DateTime? someNullableDate;
DateTime myDate;

if( someNullableDate.HasValue )
   myDate = someNullableDate.Value;

使用空合并运算符是获取可空值类型的值的另一种更简洁的方法:

DateTime myDate = someNullableDate?? default(DateTime);

1
这个解决方案比答案好多了。 - Maytham Fahmi

10

使用可空类型的最佳解决方案,我认为是其中最好的功能

DateTime newSelectedDate = myCalendarExtender.SelectedDate.GetValueOrDefault();

我认为这是更加简洁的解决方案。 - Maytham Fahmi

9
日历控件在其SelectedDate属性中返回一个Nullable<DateTime>(在C#中的简写为DateTime?),因为DateTime是一个结构体。空值允许控件具有“未选择日期”的状态。因此,在使用之前,您需要检查可为空值是否具有值。
var nullable = myCalendarExtender.SelectedDate;
var newSelectedDate = (nullable.HasValue) ? nullable.Value : SomeDefaultValue;

编辑:由于Josh的评论,以下实现更加简洁:

var newSelectedDate = myCalendarExtender.SelectedDate ?? SomeDefaultValue;

我喜欢它!


2
你可以使用以下方法简化这个过程:var newDate = nullable ?? someDefault; - Josh
1
或者你可以按照我的答案跳过所有的存在性检查。 - Chris Marisic
@Chris - 我同意;然而,有时我不想使用值类型(如DateTime)的默认值...也许我想在计算中使用DateTime.Today作为我的默认值。 - Travis Heseman

2

在C#中,您可以使用 ?? 运算符以非常简洁的方式处理可空类型。关于“如果不为空则使用它,否则使用某个默认值”概念的更短表达方式,请参见我的评论Travis的答案。它们都做同样的事情。


-1
var Endtime = DateTime.Now();
DateTime startTime = item.REPORT_TIME.HasValue ? item.REPORT_TIME.Value : Endtime;

意思是:item.item.REPORT_TIME 的类型是 system.DateTime 吗?
但是 startTime 的类型是 system.DateTime; 所以代码可以改成

`var Endtime=DateTime.Now; var startTime=item.REPORT_TIME.HasValue?Convert.ToDateTime(item.REPORT_TIME.HasValue):Endtime

`


1
你能否请格式化你的代码并且更详细地解释一下? - Souvik Ghosh
这是我第一次给出答案,如果需要的话我会进行修改。感谢您的建议。 - Ken yang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接