予想どおりfalse
に等しいこの比較を行いました
bool eq = typeof(int?).Equals(typeof(int));
今私はこのコードを持っています
List<object> items = new List<object>() { (int?)123 };
int result = items.OfType<int>().FirstOrDefault();
しかし、これは123
を返します-とにかく、その値のタイプはint?
です
どうすればいいの?
Null許容型には特別な「ボックス化」ルールがあります。 「ボックス化」とは、コードに従って、値タイプがobject
として扱われる場合です。通常の値タイプとは異なり、null許容値タイプはボックス化されますどちらかとしてnull
(通常のnull
、タイプなし)、またはnon- nullableタイプ(_T?
_のT
)。つまり、_int?
_は_int?
_ではなくint
としてボックス化されます。次に、OfType<int>()
を使用すると、int
であるすべての値を取得します。つまり、渡された単一の値ですなので、 タイプint
の。
Null許容値の型は、次のルールによってボックス化されます
HasValue
がfalse
を返す場合、null参照が生成されます。HasValue
がtrue
を返す場合、nullableのインスタンスではなく、基になる値タイプT
の値がボックス化されます。あなたの例では、あなたが価値を持っているので2番目のルールが続いています:
var i = (object)(int?)123;
少し遅いですが、あなたの質問に対するMarcの回答のほかに、CLRのNullable値型に関する追加情報を提供したいと思います。
CLRには、null許容値型のサポートが組み込まれています。この特別サポートは、boxing、unboxing、calling GetType
、calling interface methods。
たとえば、GetType()
を確認してみましょう。
Int32? x = 5;
Console.WriteLine(x.GetType());
コンソールに何が出力されると思いますか? System.Nullable<Int32
?いいえ、結果はSystem.Int32
です。
または、質問で書き留めたチェックボックスをチェックしてみましょう。
Int32? n =5;
Object o = n;
Console.WriteLine("o's type={0}", o.GetType()); // "System.Int32"
ルールは次のとおりです。
CLRはNullableインスタンスをボックス化するときに、それがnullかどうかを確認し、nullである場合、CLRは実際には何もボックス化せず、nullが返されます。 null可能なインスタンスがnullでない場合、CLRはnull可能なインスタンスから値を取り出し、ボックス化します。つまり、値が5のNullableは、値が5のboxed-Int32にボックス化されます。
最後に、CLRがNullable型からインターフェイスメソッドを呼び出すための特別なサポートを追加する方法について説明します。それを見てみましょう:
Int32? n = 5;
Int32 result = ((IComparable) n).CompareTo(5); // Compiles & runs OK
Console.WriteLine(result); // 0
上記のコードでは、n、Nullable<Int32>
、をIComparable<Int32>
、インターフェースタイプにキャストしています。ただし、Nullable<T>
タイプは、IComparable<Int32>
のようにInt32
インターフェイスを実装していません。 C#コンパイラでは、このコードをコンパイルできます。