しゅみぷろ

プログラミングとか

Nullable<T>のGetTypeについて

var i = new int?();
//i.GetType(); //NullReferenceException!!!
Console.Write(i.HasValue); //false

となる原因について色々調べてみたのでまとめようかと思います。 上記のコードでは、インスタンス化した直後のNull許容型(Nullable)に対してGetTypeメソッドを用いるとNullReferenceExceptionになる問題が発生しています。しかし、HasValueプロパティにはアクセスできます。あれ、NULLじゃなくね?って思ったんですが、原因が判明したのでめもめも。

既に知っていらっしゃる方がいらっしゃったので、そちらを見ればわかると思います。

stackoverflow.com

csharper.blog57.fc2.com

csharper.blog57.fc2.com

重要なのは、インスタンスが自身を取得する際に利用するthisキーワードのような機能がILにないということと、ではインスタンスメソッドはIL上ではどのようにしてインスタンス(自身)を参照しているのかということです。

上記のサイトを参考にすると、ILはインスタンスメソッドインスタンスを得るために、一番最初の引数をインスタンスへのポインタにしてるらしいです。ちょうどPythonなんかを思い浮かべると「あぁ、、」ってなりますね。

Nullable型は値型なので、GetTypeメソッドではインスタンスの参照を得るためにBox化されます。

上記サイトによると

Nullable 型をボックス化する際、CLR は特別な動作をします。
Nullable 型が (論理的に) null である場合、ボックス化を行わず (正真正銘の) null を返します。
Nullable 型が (論理的に) null でない場合、Nullable 型が保持している生 (?) の値をボックス化して返します。
ということで、Nullable 型に対して GetType メソッドを呼び出しても、生の値、あるいは null に対して呼び出されてしまうというわけです。

ということらしいですね!。 上記サイト様には感謝感謝・・・。