如何将DateTime.TryParse与Nullable <DateTime>结合使用?


114

我想使用DateTime.TryParse方法将字符串的datetime值转换为Nullable。但是当我尝试这个:

DateTime? d;
bool success = DateTime.TryParse("some date text", out (DateTime)d);

编译器告诉我

'out'参数未归类为变量

不知道我需要在这里做什么。我也尝试过:

out (DateTime)d.Value 

那也不行。有任何想法吗?

Answers:


122
DateTime? d=null;
DateTime d2;
bool success = DateTime.TryParse("some date text", out d2);
if (success) d=d2;

(可能有更优雅的解决方案,但是为什么不简单地做上面的事情呢?)


3
您是对的,我一直在寻找更多的单线解决方案,但我想这样做可以。不喜欢创建该临时变量,感觉很混乱。:-/似乎应该更好地支持这种情况。
布赖恩沙利文

1
请参阅Binary Worrier关于将psuedo内联到扩展方法中的建议。
大卫·阿尔珀特

4
为什么要将DateTime强制转换为DateTime?在将d2传递到TryParse之前,无需重新设置其大小写。
亚伦·鲍威尔,

@Slace-我更新了答案以纳入您的建议。
德鲁·诺阿克斯

@Jason Kealey我希望这已在VS2012中引入,否则我将不得不继续使用这段不错的代码。
Pimenta

161

正如Jason所说,您可以创建正确类型的变量并将其传递。您可能希望将其封装在自己的方法中:

public static DateTime? TryParse(string text)
{
    DateTime date;
    if (DateTime.TryParse(text, out date))
    {
        return date;
    }
    else
    {
        return null;
    }
}

...或者如果您喜欢条件运算符:

public static DateTime? TryParse(string text)
{
    DateTime date;
    return DateTime.TryParse(text, out date) ? date : (DateTime?) null;
}

或在C#7中:

public static DateTime? TryParse(string text) =>
    DateTime.TryParse(text, out var date) ? date : (DateTime?) null;

5
我可能不应该与The Skeet争论,但是...您应该调用方法Parse,因为我希望一个叫做TryParse的方法遵循TryParse约定并返回一个布尔值。;-)
Myster2015年

@Myster:在任何情况下,它都不会遵循现有的确切惯例-那些曾经Parse希望它返回DateTime并在失败时引发异常的人,对吗?但是是的,您可以做任何您想做的事...在Noda Time中,我已经命名了相关方法Parse
乔恩·斯基特

1
else关键字是不必要的(在第一个例子),因为的终点if块永远不能达到。
杰普·斯蒂格·尼尔森 Jeppe Stig Nielsen),

1
@JeppeStigNielsen:是的,没有必要-但从风格上讲,对称性可能更可取。这只是个人喜好(我也不一致……)
乔恩·斯凯特

3
@Kiquenet:使用else可以使一个或另一个路径更清晰,并且两者都返回。我反对大量嵌套的代码,但是在这种情况下,IMO确实不是问题。
乔恩·斯凯特

20

这是Jason建议的简短版本:

DateTime? d; DateTime dt;
d = DateTime.TryParse(DateTime.Now.ToString(), out dt)? dt : (DateTime?)null;

18

你不能因为 Nullable<DateTime>与的类型不同DateTime。您需要编写自己的函数来做到这一点,

public bool TryParse(string text, out Nullable<DateTime> nDate)
{
    DateTime date;
    bool isParsed = DateTime.TryParse(text, out date);
    if (isParsed)
        nDate = new Nullable<DateTime>(date);
    else
        nDate = new Nullable<DateTime>();
    return isParsed;
}

希望这可以帮助 :)

编辑: 删除了(显然)未正确测试的扩展方法,因为(试图指出“糟糕”的扩展方法)尝试更改“ this”参数的扩展方法不适用于值类型。

PS有问题的坏家伙是老朋友:)


Ya不想初始化日期(因为您将其用作外部参数)好吧,我不再挑剔!
2009年

我没有编译器,但是由于DateTime是一种值类型,扩展方法def是否可以编译?
鲁宾·巴特林克

除非您指出结果,否则结果不会返回-[TestFixture]公共类WhenExtending {[Test]公共无效TryParseShouldWork(){DateTime?x = null; var res = Externders.TryParse(x,“ 1/1/1990”); Assert.IsTrue(res)
Ruben Bartelink 09年

; Assert.That(x!= null); }}在Assert。上失败。也就是说,由于DateTime是一种值类型(在电话屏幕上,这始终是一个很好的淘汰问题:D),因此结果未得到修改
Ruben Bartelink 09年

(可以使用第一个(非扩展名),但是应该退出,而不是引用-如果总体上不适合TryXXX API,则应该使结果为空-可以肯定FDG提到了这一点。我很挑剔!
鲁本·巴特林克

4

如何创建扩展方法?

public static class NullableExtensions
{
    public static bool TryParse(this DateTime? dateTime, string dateString, out DateTime? result)
    {
        DateTime tempDate;
        if(! DateTime.TryParse(dateString,out tempDate))
        {
            result = null;
            return false;
        }

        result = tempDate;
        return true;

    }
}

2
的第一个参数dateTime是什么?从未使用过。
Mike Zboray 2012年

1
@mikez-这就是扩展方法的工作方式,编译器使用它来知道它应该是扩展方法。
Erik Funkenbusch

3
@MystereMan我知道什么是扩展方法。扩展方法更合适的签名是DateTime? TryParse(this string dateString)。这种实现方式很奇怪。
Mike Zboray

3
@mikez-那么为什么要问它是干什么的呢?当只需要日期时间时,为什么要污染字符串名称空间?目的是提供类似于DateTime.TryParse的DateTime?.TryParse
Erik Funkenbusch 2013年

1
@ErikFunkenbusch这个扩展方法将不会允许像调用语法(DateTime?).TryParse( ... )Nullable<DateTime>.TryParse( ... )。所以Mike Z是对的,这是该方法的愚蠢签名。
杰普·斯蒂格·尼尔森

1

我不明白为什么微软不处理这个。一个聪明的小实用程序方法来解决这个问题(我遇到了int的问题,但是用DateTime替换int将具有相同的效果,可能是.....

    public static bool NullableValueTryParse(string text, out int? nInt)
    {
        int value;
        if (int.TryParse(text, out value))
        {
            nInt = value;
            return true;
        }
        else
        {
            nInt = null;
            return false;
        }
    }

1

这是您正在寻找的一种衬板:

DateTime? d = DateTime.TryParse("some date text", out DateTime dt) ? dt : null;

如果要使其成为适当的TryParse伪扩展方法,则可以执行以下操作:

public static bool TryParse(string text, out DateTime? dt)
{
    if (DateTime.TryParse(text, out DateTime date))
    {
        dt = date;
        return true;
    }
    else
    {
        dt = null;
        return false;
    }
}

@robnick那和我说的有什么不同?
cpcolella

1
忽略我之前的评论(我已赞成您的解决方案!),对于最新的C#,我需要转换为null:DateTime?d = DateTime.TryParse(blah,out DateTime dt)吗?dt:(DateTime?)null;
罗宾尼克'19

1

这是单行解决方案:

DateTime? d = DateTime.TryParse("text", out DateTime parseDate) ? parseDate : (DateTime?)null;

-3

或者,如果您不担心引发的异常,则可以将TryParse更改为Parse:

DateTime? d = DateTime.Parse("some valid text");

尽管也没有布尔值指示成功,但是在某些情况下,当您知道输入文本将始终有效时,这可能是可行的。

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.