2009-03-27 14 views
33

C#でDateTimeにnullを割り当てることができないのはなぜですか?これはどのように実装されていますか?また、この機能を使用して独自のクラスをnullにできないようにすることはできますか?C#でDateTimeにNULLを使用できないのはなぜですか?

例:

string stringTest = null; // Okay 
DateTime dateTimeTest = null; // Compile error 

私はnullがdateTimeTestに割り当てられていると私はの割り当ての実行時エラーを取得する私の列にJon Skeet's NonNullable classを使用することができることをできるようにするためにC#2.0でDateTime?を使用することができることを知っていますstringTest。私はちょうどなぜ2つのタイプが異なって振る舞うのだろうかと思っています。

+0

ジョンはジョンではありません。 –

答えて

76

DateTimeは値型(struct)です。-stringは参照型(classなど)です。それが重要な違いです。参照は常にnullでもかまいません。値はゼロ(DateTime.MinValue)でもかまいません( - すなわちを使用しない限り)ことはできませんが、多くの場合nullと同じものとして解釈されます(1.1の場合)。

+0

清算に感謝します。構造体を使用してnull値を持たないクラスを作成してみませんか? –

+1

そしてデフォルト(YourWrapper)は何ですか? ;-p null参照を含む構造体です...すべての構造体*常に*デフォルトのコンストラクタを持ちます... –

+0

(または*決して* C#またはCLIについて話しているかどうかに応じてデフォルトコンストラクタを持ちません - これ以上の意見はありません) –

8

DateTimeは構造体であり、クラスではありません。参照するには、オブジェクトブラウザで「定義に移動」するか、それを参照してください。

HTH!

1

DateTimeは、intと同じ値型です。参照型(stringまたはMyCustomObjectなど)のみがnullでもかまいません。参照型は実際にヒープ上のオブジェクトの場所への "参照"を格納します。

ここにはarticleがありますMSDN article on it

+0

null可能な値の型Nullable (それ自体も構造体です) –

0

文字列はクラスですが、DateTimeは構造体です。それをnullに設定できない理由

7

ValueTypesと参照型の重要な違いは、値型にこれらの「値の意味」があることです。 DateTime、Int32および他のすべての値の型は同一性を持たないため、Int32「42」は、同じ値を持つ他のInt32と本質的に区別できません。

すべての値タイプ「オブジェクト」は、スタックまたは参照型オブジェクトの一部として存在します。特別なケースの1つは、オブジェクトやインタフェースに値型のインスタンスをキャストするときです。これは「ボクシング」と呼ばれ、単に元に戻すことができる値(「unboxed」)のみを含むダミーの参照型オブジェクトを作成します。 。

参照型は、同一性を持っています。 「新しいObject()」はGCヒープ上の別のインスタンスであるため、他の「新しいObject()」と等しくありません。いくつかの参照型はEqualsメソッドとオーバーロードされた演算子を提供し、より価値のように動作するようにします。実際には2つの異なるオブジェクトであっても、文字列 "abc"は他の "abc" Stringと同じです。

参照がある場合、有効なオブジェクトのアドレスを含むか、nullにすることができます。値型オブジェクトがすべてゼロの場合、それらは単にゼロになります。例えば。整数ゼロ、浮動小数点数ゼロ、ブール値false、またはDateTime.MinValueです。 "ゼロ"と "値の欠落/ヌル"を区別する必要がある場合は、別のブールフラグを使用するか、.NET 2.0ではNullable < T>クラスを使用する必要があります。これは単純に値とブール値フラグです。また、CLRのサポートでは、HasValue = falseのNullableのボクシングはnull参照となり、false + zeroのボックス構造ではなく、この構造体を自分で実装する場合と同じ結果になります。

1

値の型をnullにするには、他の正当な意味を持たない値を保持する必要があります。は、システムが何らかの形で「null」とみなす必要があります。追加のストレージを必要とせずに、一部の値型が最初の基準を満たすことができます。 .NETが念頭に置いてNULL可能値の概念にゼロから設計されていた場合、それはObject include a virtual IsLogicalNull property, and a non-virtualのIsNull which would returnifこのis null and, otherwise invoke its IsLogicalNull property and return the result. If .net had done this, it would have avoided the need for the quirky boxing behavior and構造体constraint ofのNullable (an emptyのNullable could be boxed as an emptyのNullable , and still be recognized as null`なので)だっただろう。それは.NET 2.0でNULL可能値型のサポートを提供することを決定した時までに

は、しかし、コードの多くはGuidDateTimeのようなもののためのデフォルト値はnullとはみなされないだろうと想定している書かれていました。 null可能な型の値の大部分は、予測可能なデフォルト値(null)にあり、型がnullの値を持ちますが、デフォルト値が設定されているため、値よりも混乱が生じます。

関連する問題