检查是否为DateTime变量分配了值


131

C#中是否有一种简单的方法来检查DateTime实例是否已分配值?

Answers:


82

在C#中拥有未分配值的变量的唯一方法是使其成为局部变量-在这种情况下,在编译时,可以通过尝试从中读取来明确地确定它不是绝对赋值的: )

我怀疑您确实想要Nullable<DateTime>(或DateTime?使用C#语法糖)-使它null开始,然后分配一个正常值DateTime(将对其进行适当地转换)。然后,您可以仅与null(或使用该HasValue属性)进行比较,以查看是否已设置“真实”值。


如何检查该值是否等于默认日期时间值。这种方法有什么明显的缺点吗?if(request.StartDateTime == default(DateTime){request.StartDateTime = DateTime.Now;}
Menol,2016年

8
@Menol:好吧,这并不能说明故意为该字段赋值的字段default(DateTime)与以这种方式开头的字段之间的区别。基本上,我将域中的一个值视为“特殊且无法正常使用”,这是我不喜欢的。
乔恩·斯基特

298

你是说这样吗?

DateTime datetime = new DateTime();

if (datetime == DateTime.MinValue)
{
    //unassigned
}

或者你可以使用Nullable

DateTime? datetime = null;

 if (!datetime.HasValue)
 {
     //unassigned
 }

5
其中只有第二个是防弹的。第一个假设框架未保证有关DateTime的未设置表示的某些内容。就我个人而言,我认为他们应该为此场景添加一个Unset静态成员。
鲁珀特·罗恩斯利

18
要添加@RupertRawnsley所说的内容,您实际上应该与default(DateTime)(它是未分配的DateTime的值)进行比较。它恰好等于MinValue,但是它可能会改变。
Tsahi Asher

32

放在这里:

public static class DateTimeUtil //or whatever name
{
    public static bool IsEmpty(this DateTime dateTime)
    {
        return dateTime == default(DateTime);
    }
}

然后:

DateTime datetime = ...;

if (datetime.IsEmpty())
{
    //unassigned
}

我喜欢这个想法,但是请注意,在不太可能发生的事件中,为DateTime变量分配了一个恰好是默认值的值,此扩展方法将返回错误的结果。避免这种情况的唯一方法是使用已经建议过的可为空的DateTime。我还是很喜欢(现在正在使用)您的答案,谢谢!
Klicker

@Klicker:谢谢您的好评,但是我不确定我是否理解您的评论。据我所知,在这种情况下,当datetime等于default(DateTime)时,==总是返回true,无论以哪种方式给datetime赋默认值。让我解释一下:实际上,我回答中的第二个片段是错误的,它不会编译,因为,如果您认为这是函数的主体,则不会分配datetime,编译器将拒绝使用它。因此,您将必须为其分配一个值。可以直接或间接将其设置为default(DateTime)。我将修改答案。
sonatique

如果在另一个上下文中datetime是类的成员,并且按原样保留,则运行时将为其分配default(DateTime)。结构的==实际上比较结构的内容,无论结构最终以何种方式填充此内容。
sonatique

我的观点仅与班级成员有关,而我的意思是。如果您具有将MinValue分配给的类级别的DateTime字段或属性,则您的IsEmpty方法将返回true,这可能不是您想要的(因为它不为空-已被分配为默认值)。我想您的方法名称将更适合作为IsDefaultValue。由于您不能真正拥有一个不能为null的DateTime IsEmpty
Klicker

@Klicker:是的,好的,知道了。您是对的:我选择的名称具有误导性。IsDefaultValue会更好
sonatique

5

DateTime是值类型,因此不能永远为null。如果您认为DateTime?(Nullable)您可以使用:

DateTime? something = GetDateTime();
bool isNull = (something == null);
bool isNull2 = !something.HasValue;

5

我刚刚发现,未分配日期时间的GetHashCode()始终为零。我不确定这是否是检查空datetime的好方法,因为我找不到任何有关为何显示此行为的文档。

if(dt.GetHashCode()==0)
{
    Console.WriteLine("DateTime is unassigned"); 
} 

1
GetHashCode由于滴答(DateTime的内部表示形式)也等于0,因此返回0。哈希代码通过以下方式计算: unchecked((int)ticks) ^ (int)(ticks >> 32);。另请参见此处:referencesource.microsoft.com/#mscorlib/system/datetime.cs,836
Ivan Kochurkin

非常感谢你。我正在尝试从C#类序列化XML文件并排除null属性。这有帮助。
吉姆·内夫


3

我会说默认值始终是new DateTime()。所以我们可以写

DateTime datetime;

if (datetime == new DateTime())
{
    //unassigned
}

2
该解决方案已经由+ Hath在2008年提出,并且+ Rupert Rawnsley在评论中补充说,它不是防弹的……
RolandBär2014年

0

我通常更喜欢在可能的情况下使用值类型的默认值来确定是否已设置它们。显然,这不可能一直都实现,尤其是对于int而言-但对于DateTimes来说,我认为保留MinValue表示未更改就足够了。与nullable相比,此方法的好处在于,您将获得一个空引用异常的位置减少了一个(可能有很多地方在访问它之前不必检查null!)


0

如果您不想担心Null值问题,例如每次使用它时都要检查null或以某种逻辑将其包装起来,并且您也不必担心偏移时间问题,那么这就是我如何解决问题:

startDate = startDate < DateTime.MinValue.AddDays(1) ? keepIt : resetIt

我只是检查默认值是否少于开始时间的一天。奇迹般有效。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.