2007年09月27日
川俣晶の縁側ソフトウェア技術雑記 total 3927 count

C# 2.0において、値型と参照型の境界線はどこにあるのか?

Written By: 川俣 晶連絡先

 やることが多く時間がないのですが、もしかしたら重要かもしれないので、メモだけ。

επιστημηさんのブログの値型/参照型より

あたしゃ参照か値かは作る人じゃなくて使う人が決めるもんだと思ってんだけども、.Netでは作る人が決めちゃうわけで、なんかこー、しっくりこないっちゅーか。

 これを読んで、C#は(というかCLIでは?)型を宣言する際に値型か参照型かを最初から決めなければならないが、その本質的な必然性とは何だったかな? と考えているうちに、話が単純ではないことに気付きました。

 C# 1.0時代、値型と参照型の相違は明瞭です。それらはメモリを確保する方法が違い、それに伴い必然的にパフォーマンス、メモリ消費量、寿命、継承、コンストラクタ、etcに相違が生じます。

 たとえば、ローカル変数として値型の値を作れば、寿命はスコープを抜けるまでです。しかし、参照型の値を作ると、その寿命はガベージコレクションで回収されるまでです。(このあたりの説明は大ざっぱすぎて不正確かもしれない。以下の同じ)

 ところが、C# 2.0になるとこの単純なモデルが通用しなくなります。

 たとえば、ローカル変数として値型の変数を宣言し、それを匿名メソッドから参照すると、その「値型のローカル変数」の寿命は匿名メソッドが有効である限り延命されます。つまり、シンプルなint a;のようなローカル変数が、匿名メソッドから参照されているか否かで振るまいが全く変わってしまうわけです。

 具体的な実装としては、匿名メソッドから参照される値型の変数は、内部的に生成されるクラスに格納され、このクラスのインスタンスが匿名メソッドから参照されます。しかし、このようなメカニズムはソースコードからは見えない形で用意されていて、表面的には値型のローカル変数の寿命が延びたように見えます。

 では、そのような実装レベルの構造を忘れ、構文上の表面的なレベルにおいて、C# 2.0の値型と参照型の本質的な差とはどこに求められるのか?

 疑問のメモなので、結論は無し。