ボクシング.boxing


POINT 値型を object に wrap して格納する機能のこと。 まとめ また、この2つはC++にもない機能であり、既存のプログラム言語の利用者は戸惑うかもしれない。 便利な機能を使いこなすには、それらを正しく理解することが欠かせない。  複数のデータを一括して扱う処理を記述する場合に、 どのようなデータでも収納できる便利な機能を記述できるとプログラムがすっきりする。 だが、実用言語で、これを達成したものは多くはない。 例えばJavaでは、数値型はクラスではないため 任意のクラスのインスタンスを扱う入れ物となるクラスを設計しても、 そのままでは数値を格納できない。 そのため、数値を格納するラッパ・クラス(wrapper class)のインスタンスに一度数値を入れてから それを格納する必要がある。 Visual Basic 6.0のVariant型は何でも格納できるのだが、 その代わり 値を入れるときは普通の代入 参照を代入する場合はsetステートメントと使い分ける必要がある。 POINT  これに対して、C#は、すべてのクラスのスーパー・クラスを辿っていくと、 最後にたどり着くobject型に、すべてのデータの参照を格納できる。 ちなみに、object は System.Object の別名。 実際に 整数、実数、文字列、Structs、クラスの5種類の情報を1個のobject型の配列に代入できる。
{ public struct Structs1 {} public class Class1 { public static int Main(string[] args) { object [] test = new object[5]; test[0] = (int)1; test[1] = (float)0.1; test[2] = (string)"Hello!"; test[3] = new Structs1(); test[4] = new Class1(); for( int i=0; i<5; i++ ) { Console.WriteLine( "Class={0}, Value={1}", test[i].GetType().FullName, test[i].ToString() ); } return 0; } } }
これまでの常識では、「object」はクラスであり、クラスは参照型なのだから 整数値などは代入できないはずだ。 配列testの各要素について、データ型と値を表示する。 GetType( )はデータ型に関する情報を取得するためのメソッドで 「GetType( ).FullName」によって そのデータ型のネームスペースを含むフルネームが得られる。 GetType( )はデータ型を得るためのメソッドでどのオブジェクトでも使用できる。 FullName は、そのデータ型の namespace を含むフルネームを得るためのプロパティ。 クラスや Structs に対して、ToString( )をオーバーライドせずに呼び出すと、 そのクラスや Structs の名前を返す機能が備わっている。 なぜなら、objectはクラスであり、クラスは参照型であって、値型とは違うからだ。 値型の整数が簡単に代入できるわけがない。 つまり、値型である整数、実数、文字列、Structs は object 型に代入できないのが筋なのである。 C#の「ボクシング(boxing)」と呼ばれる機能により値型を参照型に代入できる。 C#では、値型の値を object などの参照型に代入しようとすると、ボクシングという機能が自動的に挿入される。 ボクシングは、値型を包み込むクラスを自動的に生成する。 クラスは参照型なので、そのまま参照型として利用できる。 object 型の変数には、C#のあらゆる型のデータへの参照が代入できる。 これにより、どんなデータ型でも収納できる便利なクラスが非常に作りやすくなっている。 ボクシングとは要するに、暗黙のうちにクッションとなるオブジェクトを自動的に生成して、 そのなかに値型の値をコピーすることを意味する。 元々の値型の値を参照するわけではない。 また、あくまでボクシングはデータをコピーする行為であるため、 元のデータを変更しても、それが反映されない。 このようにボクシングは便利ではあるが、込み入った使い方をしようとすると、 トラブルの元になる場合もある。 値型と参照型の違いは、きちんと意識して利用するようにしよう。