web-dev-qa-db-ja.com

intと入力しますか?対型int

予想どおりfalseに等しいこの比較を行いました

bool eq = typeof(int?).Equals(typeof(int));

今私はこのコードを持っています

List<object> items = new List<object>() { (int?)123 };
int result = items.OfType<int>().FirstOrDefault();

しかし、これは123を返します-とにかく、その値のタイプはint?です

どうすればいいの?

45
Dr. Snail

Null許容型には特別な「ボックス化」ルールがあります。 「ボックス化」とは、コードに従って、値タイプがobjectとして扱われる場合です。通常の値タイプとは異なり、null許容値タイプはボックス化されますどちらかとしてnull(通常のnull、タイプなし)、またはnon- nullableタイプ(_T?_のT)。つまり、_int?_は_int?_ではなくintとしてボックス化されます。次に、OfType<int>()を使用すると、intであるすべての値を取得します。つまり、渡された単一の値ですなので、 タイプintの。

59
Marc Gravell

Null許容値の型は、次のルールによってボックス化されます

  • HasValuefalseを返す場合、null参照が生成されます。
  • HasValuetrueを返す場合、nullableのインスタンスではなく、基になる値タイプTの値がボックス化されます。

あなたの例では、あなたが価値を持っているので2番目のルールが続いています:

var i = (object)(int?)123;
9
Johnny

少し遅いですが、あなたの質問に対する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#コンパイラでは、このコードをコンパイルできます。

4
Farhad Jabiyev