DateTime変数に値が割り当てられているかどうかを確認する


131

C#内で、DateTimeインスタンスに値が割り当てられているかどうかを確認する簡単な方法はありますか?

回答:


82

C#で値が割り当てられていない変数を使用する唯一の方法は、その変数をローカル変数にすることです。この場合、コンパイル時に、変数を読み取ろうとしても、その変数が確実に割り当てられていないことがわかります。 )

私はあなたが本当にNullable<DateTime>(またはDateTime?C#構文糖を使って)望んでいるのではないかと思います-それnullを最初にして通常のDateTime値を割り当てます(適切に変換されます)。次に、と比較null(またはHasValueプロパティを使用)して、「実際の」値が設定されているかどうかを確認できます。


値がデフォルトの日時値と等しいかどうかを確認するのはどうですか。このアプローチには目立たない欠点はありますか?if(request.StartDateTime == default(DateTime){request.StartDateTime = DateTime.Now;}
Menol

8
@Menol:意図的に値が指定されたフィールドとdefault(DateTime)、最初からそうであったフィールドの違いはわかりません。基本的には、ドメイン内の1つの値を「特別で通常の使用には使用できない」として扱います。
Jon Skeet、2016年

298

そういう意味ですか:

DateTime datetime = new DateTime();

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

またはNullableを使用できます

DateTime? datetime = null;

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

5
これらの2番目だけが防弾です。1つ目は、フレームワークで保証されていない、DateTimeの未設定の表現について想定しています。個人的には、このシナリオではUnset静的メンバーを追加する必要があったと思います。
Rupert Rawnsley 2013年

18
@RupertRawnsleyの発言を追加するには、実際には、割り当てられていないDateTimeの値であるdefault(DateTime)と比較する必要があります。たまたまMinValueと同じですが、変更される可能性があります。
Tsahi Asher、2015

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変数にたまたまデフォルト値である値が割り当てられているという、ありそうもないイベントでは、この拡張メソッドは誤った結果を返すことに注意してください。これを回避する唯一の方法は、すでに提案されているnull可能なDateTimeを使用することです。私はまだあなたの答えが本当に好きです(そして今使っています)、ありがとう!
Klicker

@Klicker:素敵なコメントをありがとうございましたが、私はあなたの発言を理解しているとは思いません。この場合、==がわかる限り、この場合、datetimeがdefault(DateTime)と等しい場合、datetimeの終了にデフォルト値が割り当てられる方法が何であれ、常にtrueを返します。説明させてください:実際に私の答えの2番目のスニペットは間違っています、これはコンパイルされません。これが関数の本体であると考える場合、datetimeは割り当てられておらず、コンパイラーはそれを使用しないためです。したがって、値を割り当てる必要があります。直接または間接的にdefault(DateTime)にすることができます。回答を修正します。
sonatique

また、別のコンテキストでdatetimeがクラスのメンバーであり、それがそのままの場合、ランタイムはそれにdefault(DateTime)を割り当てます。構造体の==は、実際に構造体の内容を比較します。構造体が最終的にこのコンテンツで満たされる方法は何であってもです。
sonatique

私のポイントは本当にクラスのメンバーにのみ関係しており、私が言いたいのは MinValueを割り当てたクラスレベルのDateTimeフィールドまたはプロパティがある場合、IsEmptyメソッドはtrueを返しますが、これはおそらく望んでいるものではありません(空ではないため、デフォルト値が割り当てられています)。あなたのメソッドの名前はとしてより適してIsDefaultValueいると思います。nullを許容しないDateTimeを実際に持つことはできないためですIsEmpty
Klicker

@クリッカー:ああ、はい、わかりました。あなたが正しい:私が選んだ名前は誤解を招くものです。IsDefaultValueよかっただろう
sonatique

5

DateTimeは値型であるため、nullにすることはできません。あなたはDateTimeを考えるなら?(null可能)使用できます:

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

5

割り当てられていない日時のGetHashCode()が常にゼロであることを知りました。これがnullの日時をチェックするための良い方法であるかどうかはわかりません。これは、この動作が表示される理由に関するドキュメントが見つからないためです。

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
+ルパート・ローンズリーがコメントとして追加として、このソリューションはすでに、2008年に+かれらによって与えられた、防弾...ではありません
ローランドベーア

0

一般に、可能な場合は、値タイプのデフォルト値を使用して、それらが設定されているかどうかを判断することをお勧めします。これは明らかに、特にintでは常に可能ではありません。ただし、DateTimesの場合、MinValueを予約して、変更されていないことを示すことで十分だと思います。nullableに対するこれの利点は、null参照例外が発生する場所が1つ少ないことです(おそらく、アクセスする前にnullをチェックする必要がない場所がたくさんあります)。


0

使用するたびにnullをチェックしたり、ロジックでラップしたりするなど、null値の問題について心配する必要がなく、オフセット時間の問題についても心配する必要がない場合は、私が問題を解決した方法:

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

デフォルト値が時間の開始後1日未満であることを確認します。魅力のように機能します。

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