Nullable <DateTime>でDateTime.TryParseを使用するにはどうすればよいですか?


115

DateTime.TryParseメソッドを使用して、文字列の日時値をNullableに取得したいのですが。しかし、これを試してみると:

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

コンパイラは私に言っています

'out'引数は変数として分類されていません

ここで何をする必要があるかわかりません。私も試しました:

out (DateTime)d.Value 

それも機能しません。何か案は?

回答:


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

(もっとエレガントな解決策があるかもしれませんが、なぜあなたは上記のように単に何かしませんか?)


3
あなたが正しい、私はそれを成し遂げるためにワンライナーのより多くを探していました、しかし、これはそうするであろうと思います。その一時変数を作成するのは好きではありません。:-/このシナリオのように思われるサポートを改善する必要があります。
Brian Sullivan

1
それを拡張メソッドに疑似インライン化するというBinary Worrierの提案を参照してください。
デビッドアルパート

4
なぜDateTimeをDateTimeにキャストするのですか?TryParseに渡す前に、d2を再度ケースに入れる必要はありません。
アーロンパウエル

@Slace-私はあなたの提案を組み込むために答えを更新しました。
Drew Noakes、

@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について議論すべきではありませんが、TryParseというメソッドがTryParse規則に従ってブール値を返すことを期待しているため、Parseメソッドを呼び出す必要があります。;-)
Myster

@Myster:どちらの場合も、既存の正確な規則には従いません。これまでは、失敗すると例外がParse返さDateTimeれて例外がスローされることを期待していましたか?しかし、はい、あなたはあなたがやりたいことを何でもすることができます...そして野田タイムでは、Parse代わりに関連するメソッドに名前を付けました。
Jon Skeet、2015

1
elseエンドポイントので、キーワードは(あなたの最初の例では)不要であるifブロックに到達することはできません。
Jeppe Stig Nielsen 2017

1
@JeppeStigNielsen:はい、必要ありません-しかし、対称的にはスタイル的に好ましいかもしれません。それは単なる個人的な好みです(そして私も一貫していません...)
Jon Skeet 2017年

3
@Kiquenet:elseを使用すると、どちらか一方のパスが選択され、両方が戻ることが明確になります。大量にネストされたコードには反対ですが、この場合はIMOの問題ではありません。
Jon Skeet 2017年

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 hoorパラメータを変更しようとする拡張メソッドが値型では機能しないためです(いくつかの悪いhoorによって指摘されています)。

PS問題のBad Hoorは古い友達です:)


日付を初期化したくない[out paramとして使用しているので] OK、うるさいのはやめます!
Ruben Bartelink 2009年

私にはコンパイラーはありませんが、DateTimeは値タイプなので、拡張メソッドdefはコンパイルされますか?
Ruben Bartelink 2009年

あなたがそれをしない限り、結果は返されません-[TestFixture] public class WhenExtending {[Test] public void TryParseShouldWork(){DateTime?x = null; var res = Externders.TryParse(x、 "1/1/1990"); Assert.IsTrue(res)
ルーベンバルテリンク2009年

; Assert.That(x!= null); }}はAssert.Thatで失敗します。つまり、DateTimeは値の型であるため、結果は変更されません(これは、電話画面では常に良い雑草の質問です:D)
Ruben Bartelink

(最初の(非拡張)の1つは機能しますが、refではなくoutである必要があります。また、一般にTryXXX APIに適合しない場合は結果をnullにする必要があります-FDGがそれを言及していることを確認してください。私はうるさい!
ルーベンBartelink 2009年

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-これが拡張メソッドの動作方法であり、コンパイラが拡張メソッドであることを認識するために使用されます。
エリックファンケンブッシュ2013

3
@MystereMan拡張メソッドとは何か知っています。拡張メソッドのより適切な署名はですDateTime? TryParse(this string dateString)。この実装は奇妙です。
Mike Zboray、2013

3
@mikez-では、なぜそれが何のためにあるのか尋ねたのですか?日時にのみ必要なときに文字列の名前空間を汚染するのはなぜですか?目的は、DateTime?.TryParseに類似したDateTime?.TryParseを提供することです
Erik Funkenbusch 2013

1
@ErikFunkenbuschこの拡張メソッドでは、またはのような呼び出し構文許可されません。だからマイクzは正しいです、これはメソッドの愚かな署名です。(DateTime?).TryParse( ... )Nullable<DateTime>.TryParse( ... )
Jeppe Stig Nielsen 2017

1

マイクロソフトがこれを処理しなかった理由はわかりません。これに対処するためのスマートな小さなユーティリティメソッド(私はintに問題がありましたが、intをDateTimeで置き換えると同じ効果が得られます.....

    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

これはあなたが探している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
私の以前のコメントを無視します(私はあなたのソリューションに賛成しました!)、nullをキャストするために必要な最新のC#:DateTime?d = DateTime.TryParse(blah、out DateTime dt)?dt:(DateTime?)null;
ロブニック

1

これが単一行のソリューションです。

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

-3

または、発生する可能性のある例外に関心がない場合は、ParseのTryParseを変更できます。

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

成功を示すブール値もありませんが、入力テキストが常に有効であることがわかっている状況では実用的です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.