2012-10-04 22 views
8

私はクレイジーな運転をしている同僚からこのクイズを受け取りました。このコードのスニペットの場合:Nullable型GetType()が例外をスローする

var x = new Int32?(); 
string text = x.ToString(); // No exception 
Console.WriteLine(text); 
Type type = x.GetType(); // Bang! 

なぜ()を.ToString最初の部分は、例外をスローせずに動作しないと、その後はgettypeへの呼び出しは()とNullReferenceExceptionがスローされますか?

答えて

17

ToStringoverridden in Nullable<T>であるため、電話をかけるためにボクシングは必要ありません。

GetType()は仮想メソッドではないため、オーバーライドされないため、呼び出しが行われる前に値がボックス化されています。ボクシングの場合、nullable値型のnull値は、ヌル参照。 参照型で宣言さM場合

インスタンス関数メンバである:

ボクシング理由は、C#4仕様のセクション7.5.5にあるが

  • ..
  • Eのタイプが値タイプである場合、Eをに変換するボクシング変換(4.3.1)が実行されます。、およびEは、次の手順でタイプobjectと見なされます。

    var x = new Int32?(10); 
    

    はあなたが起因して、再び、typeof(int)と同じであるタイプで終わるだろう。この場合、Mはあなたが持っていた場合、そのSystem.Object

注意のメンバーである可能性がありボクシング。値fooを作成して、foo.GetType()が通常のGetType()メソッドを使用してnull値型を返すような方法はありません。 (あなたはもちろんの新しいGetType()メソッドを作成することもできますが、それは側の問題:)

の(使用だ「バン!」の著者はクイズが私であってもよい示唆している。それはだ場合狂気あなたを駆動させるための謝罪case)。

+0

しかし、なぜ最後の行を置き換えますか:var boxed =(Int32)x;代わりにInvalidOperationExceptionをスローしますか?そのボクシングではないと同じ例外をスローする必要がありますか? – kabaros

+0

@kabaros:いいえ、それは全くボクシングではありません。 'Int32?'も 'Int32'も参照型ではありません。これは、C#4仕様のセクション6.2.3で説明されている明示的な変換です。 –

+1

もちろん、もちろんそれは完璧な意味合いがあります。どうもありがとう。あなたが私たちを夢中にさせるために許されたので、素晴らしい本 – kabaros