C#と諸々

C#がメインで他もまぁ諸々なブログです
おかしなこと書いてたら指摘してくれると嬉しいです(´・∀・`)
つーかコメント欲しい(´・ω・`)

2008/06/20 10:53
窓際プログラマーの独り言 -C#の話題を中心に:Nullable型のType より


int? a = 10;
Type type = a.GetType();
Console.WriteLine(type.Name);

を実行すると、

Int32

って表示されるんだ。



a = null;
type = a.GetType();

だと、
「オブジェクト参照がオブジェクト インスタンスに設定されていません。」
と、例外が発生する。


へー、そんな動きするんですね。
ちょっと調べてみましたところ、CLR の動作によるもののようでした。


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


# ちなみに、C# コンパイラが原因と予想して調べ始めたのですが、見事に外れました ^^;
タグ: .NET C# CLR


はじめまして。いつもコッソリ来ています。
Gushwellさんとこのブログ見て「へぇ~、でも何故??」と思ったので
ヘルプのNullable<T>を見て「ボックス化とボックス化解除」も読みました。
それでも理由はわかりませんでしたorz
それでググってみたら、よこけんさんのこのエントリが1つめに出てきました。
すでに同じことに気付いている人もいるんだって思ったら、ネタもとが
Gushwellさんでしたのでおかしかったですw
ボックス化が関係しているということと、Nullableが値型だってことで、
1つのことであわせて3回へぇ~って思いました♪

2008.06.20 13:54 URL | Streetw☆ #- [ 編集 ]


Streetw☆ さん、はじめまして

> すでに同じことに気付いている人もいるんだって思ったら
全然気づいていなかったです^^;

> ボックス化が関係しているということと、Nullableが値型だってことで
Nullable 型って C# や VB 上では null を代入できる (ように見える) から、つい参照型のように勘違いしちゃうんですけど、実際は、単に bool 値で論理的に null を表してるだけなんですよね。
値型にした理由は、たぶんパフォーマンスの問題だと思います。

2008.06.20 23:03 URL | よこけん #Ay6tTHf6 [ 編集 ]


>値型にした理由は

この辺ですかね.
http://www.divakk.co.jp/blog/aoyagi/archive/2005/08/10/6962.aspx
http://www.divakk.co.jp/blog/aoyagi/archive/2005/08/18/6977.aspx
http://www.divakk.co.jp/blog/aoyagi/archive/2005/08/25/7001.aspx

2008.06.22 17:15 URL | NyaRuRu #.70yccGM [ 編集 ]


ほほー。動作的には参照型でも実現できると思ってましたが、

> int? i = 1;
> object o = i;
> int x = (int)o;

このコードを期待通りに動作させるには参照型では無理なのですね。
「値型で実現」+「Nullable のボックス化・アンボックス化で CLR が特別な動作をする」という条件が揃わなきゃいけない、と。

参照型では無理な理由は、NyaRuRu さんの記事 (http://d.hatena.ne.jp/NyaRuRu/20051115/p1) に書かれている 「C# はキャスト演算子のオーバーロードを許しているものの,これらは単なるシンタックスシュガーで,MSIL レベルではメソッド呼び出しに過ぎません.」 が理由ですね。

2008.06.22 18:43 URL | よこけん #Ay6tTHf6 [ 編集 ]


あーすみません.アンカーのミスです.

「値型にした理由」じゃなくて,「CLR が特別な動作をする理由」ところに付けたつもりで貼ってました.

値型にした理由は、私もパフォーマンスじゃないかと予想していますが,それが明確に述べられていた資料があったかというと,すぐには思い出せないです.

2008.06.22 20:53 URL | NyaRuRu #.70yccGM [ 編集 ]


なるほど、了解です
でも NyaRuRu さんがアンカーミスしていなかったら、僕はこのことに気付かなかったかと ^^;

2008.06.22 21:18 URL | よこけん #Ay6tTHf6 [ 編集 ]












トラックバックURL↓
http://csharper.blog57.fc2.com/tb.php/221-19996e37