質問
以下が禁止されている理由
Nullable<Nullable<int>>
一方、
struct MyNullable <T>
{
}
MyNullable<Nullable<int>>
ではない
解決
これは、構造体の制約が実際には 'null不可を意味するためです。 'は、構造体であるにも関わらず、Nullableがnullable(値nullを受け入れることができる)であるため、 Nullable&lt; int&gt;
は外側のNullableに対する有効な型パラメータではありません。
これは、制約のドキュメント
で明示されています。ここでT:struct
type引数は値型でなければなりません。 Nullable以外の任意の値タイプを指定できます。
詳細については、Nullable型の使用(C#プログラミングガイド)を参照してください。
その理由を知りたい場合は、実際の言語設計者のコメントが必要です。しかし、私はそれを仮定します:
- 現在の形式でNullableを実現するために必要なコンパイラーとプラットフォームの変更は非常に広範囲です(2.0リリースへの比較的最後の追加でした)。
- これらには、混乱を招く可能性のあるエッジケースがいくつかあります。
intと同等の許可??言語がNullable &lt; Nullable&lt; null&gt;&gt;
とNullable &lt; null&gt;
を区別する方法も、以下に対する明白な解決策も提供しないため、混乱するだけです。
Nullable<Nullable<int>> x = null;
Nullable<int> y = null;
Console.WriteLine(x == null); // true
Console.WriteLine(y == null); // true
Console.WriteLine(x == y); // false or a compile time error!
trueを返すことは、非常に複雑で、Nullable型を含む多くの操作でかなりのオーバーヘッドになります。
CLRの一部の型は「特殊」です。例は、コンパイラとランタイムが相互に使用される実装について多くを知っているという点で、文字列とプリミティブです。 Nullableはこの方法でも特別です。他の領域ではすでに特殊なケースになっているため、 where T:struct
のアスペクトはそれほど重要ではありません。これの利点は、Nullableを除いてどれもnullと比較できないため、ジェネリッククラスの構造体を処理することです。これは、jitが t == null
を常にfalseと安全に見なすことができることを意味します。
2つの非常に異なる概念が相互作用できるように言語が設計されている場合、奇妙で混乱したり、危険なエッジケースに陥りがちです。例として、Nullableと等値演算子を考えます
int? x = null;
int? y = null;
Console.WriteLine(x == y); // true
Console.WriteLine(x >= y); // false!
structジェネリック制約を使用するときにNullableを防止することにより、多くの厄介な(および不明瞭な)エッジケースを回避できます。
これを義務付ける仕様の正確な部分については、セクション25.7から(強調鉱山):
値型の制約は、型パラメーターに使用される型引数を指定します 値型(&#167; 25.7.1)でなければなりません。 NULL不可の構造体型、列挙型、または型 値型制約を持つパラメーターは、この制約を満たします。型パラメーター 値型制約を持つことは、consistrator-constraintも持たないものとします。 System.Nullable型は、Tのnull入力不可の値型制約を指定します。 このように、再帰的に構築された形式の型T ??およびNullable
&lt;
Nullable&lt;
T&gt;&gt;
は禁止されています。
他のヒント
Nullable
で使用できるのはnull以外の値タイプのみです。 Nullable
自体はnull可能なので、この方法でのネストは禁止されています。
http://msdn.microsoft.com/en-us/libraryから/kwxxazwb.aspx
public Nullable( T value )
タイプ:T値タイプ。
Nullableは特別です。CLRに組み込まれているNullable型のボックス化とボックス化解除が明示的にサポートされているためです。
Nullable&lt; T&gt;
に対してMSIL box
命令を使用すると、実際には null
が結果として得られます。ボックス化されたときにnullを生成する他の値タイプはありません。
アンボックス化には同様の対称的なサポートがあります。
Nullableのジェネリック型パラメーターは、それ自体がNullableでない型(つまり、値型)でなければなりません。これは私が受け取るC#コンパイラの警告であり、意味があるようです。とにかく、どうしてそんなことをしたいの?私は個人的には、そのような宣言でさえ、何の役にも立ちませんし、ほとんど意味がありません。
Nullableを使用すると、値が存在するかどうか(null)の意味で、値型を取得して参照型のようにすることができます。参照型は既にnull許容であるため、許可されません。
MSDN から引用:
Nullable(T)構造はサポートします 値型のみをnull許容として使用する 参照型は 設計上ヌル可能。