40

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

例:

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

DateTime?C# 2.0 で null を dateTimeTest に割り当てることができることと、Jon Skeet の NonNullable クラスを文字列で使用して、stringTest の割り当てで実行時エラーを取得できることを知っています。なぜ 2 つのタイプの動作が異なるのか不思議に思っています。

4

6 に答える 6

88

DateTimeは値型 ( struct) で、文字列は参照型 (classなど) です。それが重要な違いです。参照は常に null にすることができます。値は(特に 1.1 では) null と同じものとして解釈されることが多く、ゼロ化 ( )することはできますが (使用しない限りNullable<T>- つまりDateTime?)できません。DateTime.MinValue

于 2009-03-27T12:07:43.260 に答える
9

DateTime はクラスではなく構造体です。「定義に移動」を実行するか、オブジェクト ブラウザで参照してください。

チッ!

于 2009-03-27T12:08:27.703 に答える
7

ValueType と参照型の重要な違いは、値型にはこれらの「値のセマンティクス」があるということです。DateTime、Int32、およびその他すべての値の型には ID がありません。Int32 の "42" は、同じ値を持つ他の Int32 と本質的に区別できません。

すべての値型「オブジェクト」は、スタック上または参照型オブジェクトの一部として存在します。特別なケースの 1 つは、値型インスタンスをオブジェクトまたはインターフェイスにキャストする場合です。これは「ボックス化」と呼ばれ、抽出して戻すことができる値のみを含むダミーの参照型オブジェクトを作成するだけです (「ボックス化解除」)。 .

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

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

于 2009-03-27T12:31:06.480 に答える
1

DateTime は int と同じ値型です。参照型 (文字列や MyCustomObject など) のみを null にすることができます。参照型は、実際にはヒープ上のオブジェクトの場所への「参照」を格納します。

これは私が見つけた記事で、それをよりよく説明しています。これがMSDNの記事です

于 2009-03-27T12:09:00.263 に答える
1

値の型が null であるためには、それが保持できる他の正当な意味を持たず、システムが何らかの形で "null" と見なす必要があることを認識できる値が存在する必要があります。一部の値の型は、追加のストレージを必要とせずに最初の基準を満たすことができます。.net が null 許容値の概念を念頭に置いてゼロから設計されていた場合、Object include a virtualIsLogicalNull property, and a non-virtualIsNull tr​​ueこのIsLogicalNull struct Nullable Nullable Nullable null`) を持つことができたはずwhich would returnです。ifis null and, otherwise invoke itsproperty and return the result. If .net had done this, it would have avoided the need for the quirky boxing behavior andconstraint of(an emptycould be boxed as an empty, and still be recognized as

Guidただし、.net Framework 2.0 で null 許容値型のサポートを提供することが決定されるまでに、や などのデフォルト値DateTimeが と見なされないことを想定した多くのコードが作成されていましnullた。null 許容型の値の多くは予測可能なデフォルト値 (つまりnull) にあるため、値を持っていても別のnull値にデフォルト設定された型を持つと、値よりも混乱が大きくなります。

于 2012-05-30T15:19:04.007 に答える
0

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

于 2009-03-27T12:10:09.463 に答える