日期时间 "null" / 未初始化的值是什么?

321
如何处理应能包含未初始化值(相当于 null)的 DateTime?
我有一个类,其中可能设置 DateTime 属性值或不设置。我打算将属性持有者初始化为 DateTime.MinValue,这样可以轻松地进行检查。
我已经搜索了很多但找不到解决方案。我想这是一个相当普遍的问题,你怎么处理?
16个回答

501

对于普通的DateTime,如果您根本不初始化它们,则它们将匹配DateTime.MinValue,因为它是一个值类型而不是引用类型。

您还可以使用可空的DateTime,例如:

DateTime? MyNullableDate;

或者是更长的形式:

Nullable<DateTime> MyNullableDate;

最后,有一种内置的方式来引用任何类型的默认值。对于引用类型,它返回null,但对于我们的DateTime示例,它将返回与DateTime.MinValue相同的值:

default(DateTime)

或在更近的C#版本中,

default

10
如果您提供如何使用它的示例,将会大有帮助。在数据库中如何分配可能为DBNull的DateTime到可空的DateTime? - kirk.burleson
10
值得注意的是,当你使用null来初始化它们时,它们会被分配DateTime.MinValue - Jeff LaFay
2
@kirk.burleson 那看起来像是一个单独的问题。 - CompuChip
你需要使用 MyNullableDate=date; 来设置它,使用 MyDate = MyNullableDate.Value; 从中读取,以及使用 if(MyNullableDate.HasValue) 来检查它是否为空。 - satibel
为了澄清一下答案中的“finally” - Nullable<DateTime>(DateTime?)的默认值为null,因为Nullable<T>创建了一个引用类型。 - ryanwebjackson

98

如果您使用的是.NET 2.0(或更高版本),您可以使用可空类型:

DateTime? dt = null;
或者
Nullable<DateTime> dt = null;

后来:

dt = new DateTime();

您可以通过以下方式检查该值:

if (dt.HasValue)
{
  // Do something with dt.Value
}

或者您可以像这样使用它:

DateTime dt2 = dt ?? DateTime.MinValue;

您可以在此处阅读更多:
http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx


1
即使在较早的 .NET 版本中,您也可以使用可空类型,无需使用 3.0 版本。 - stephenbayer
1
它是在.NET 2.0中出现的,对吧?问号语法是在3.5版的VB.NET中添加的,但我相信它自2.0版起就已经存在于C#中了。 - David Mohundro
1
可空类型在 .Net 2.0 中可用。C# 自 2.0 版本起就有了简写的 ? 符号。只有 VB.Net 在 2.0 版本中没有简写的 ?,但您可以使用 Nullable(Of DateTime)。 - Mendelt
对于最后一段代码,我会这样说:DateTime dt2 = dt ?? DateTime.MinValue; - Joel Coehoorn
我会使用 dt.GetValueOrDefault() -- 这是最高效的选项。 - CompuChip

45

以下方法同样有效

myClass.PublishDate = toPublish ? DateTime.Now : (DateTime?)null;
请注意,属性 PublishDate 应该是 DateTime 类型?

41

DateTime?MyDateTime {get; set;}

MyDateTime = (dr["f1"] == DBNull.Value) ? (DateTime?)null : ((DateTime)dr["f1"]);

4
这帮助我发现仅传递null是行不通的。必须使用(DateTime?)null - Inphinite Phractals

14

我建议使用可空类型

DateTime? myDate而不是DateTime myDate


8

您可以将DateTime设置为可空类型。默认情况下,DateTime不可为空。您可以通过两种方式使其可为空。一种是在DateTime类型后面加上问号符号DateTime? myTime,另一种是使用泛型Nullable。

DateTime? nullDate = null;

或者

DateTime? nullDate;

8
值得注意的是,尽管 DateTime 变量不能为 null,但仍然可以与 null 进行比较而不会出现编译器错误:
DateTime date;
...
if(date == null) // <-- will never be 'true'
  ...

6
你可以使用可空类。
DateTime? date = new DateTime?();

值得注意的是,这将为您提供与实例化非空 DateTime 不同的行为。如先前所述,new DateTime() 将有效地给您 DateTime.Min,而 new DateTime?() 将导致 null。 - Vitoc

6
您可以使用可空的DateTime来实现这个功能。
Nullable<DateTime> myDateTime;

或者以这种方式编写:

DateTime? myDateTime;

5
我通常将时间设置为DateTime.MinValue。这样,我就不会收到任何NullErrorException的错误提示,并且可以将其与我知道未设置的日期进行比较。

8
在我看来,这意味着你不能区分“我真的需要一个 DateTime”和“它是可选的”- Nullable<DateTime> 是一个更好的解决方案。请注意,IMO表示“依我之见”。 - Jon Skeet
我真的不明白你的评论。是的,我知道当DateTime远离现实时,就像它是null一样... - Patrick Desjardins
2
这样做很方便,但我认为DateTime.MinValue是一个值,而不是一个特殊情况。这只会在后面引起问题。我会选择Nullable<DateTime>。 - spoulson
3
我认为你在我的回答中漏掉了一些东西,Spoulson写了一些东西然后我在回答。至于公共成员,嗯,这不是一样的,你知道的。就像String.Empty或null一样。你可以两者都使用,不是因为String.Empty更好而null就是错误的。无论如何。 - Patrick Desjardins
1
我赞同Daok的观点。这可能不是“按照书本上的”方法,但它比遇到NullReferenceException或处理繁琐的Nullable类型要好得多。此外,有多少应用程序实际上需要引用公元1年1月1日的日期? - Jacobs Data Solutions
显示剩余4条评论

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