全てのクラスは、 System.Object から派生したクラスであり、Object 型に変換することができます。
しかし、Object 型は参照型であり構造体のような値型は変換できるのかという疑問が残ります。
C#では、このような変換をサポートするために ボクシング と呼ばれる処理が行われます。
この処理は、値型の値をobject などの参照型に代入しようとすると、自動的に参照型のインスタンスが生成されます。
この生成されたインスタンスに値型の値をコピーすることでボクシングが実現されます。
これは、元の値型の値を参照するわけでは無いので、ボクシング後の値を変更しても元のデータには反映されることはありません。
具体的な内部処理は、スタックの値をヒープにコピーして、コピー先への参照がスタックに渡されます。
struct Sample // 構造体
{
public override string ToString()
{
return "ボクシング変換。";
}
}
class MyClass
{
static void Main()
{
Sample obj = new Sample();
System.Object box = obj; // 構造体を参照型にキャスト
GetObject(box);
int i = 3;
System.Object ibox = (object)i; // ボクシング
}
static void GetObject( System.Object obj )
{
Console.WriteLine(obj);
}
}
アンボクシングは、ボクシングされた参照型を元の値型に変換する処理です。
変換を行うには、ボクシングされた参照型の元となる型と互換性がなければいけません。
これは、値型にインスタンスの値をコピーして渡すので、ボクシング前とアンボクシング後の値型は別物となります。
struct Sample // 構造体
{
public override string ToString()
{
return "ボクシング変換。";
}
}
class MyClass
{
static void Main()
{
Sample obj = new Sample();
System.Object box = obj; // ボクシング
Sample unbox = (Sample)box; // アンボクシング
int i = 3;
System.Object ibox = (object)i; // ボクシング
int iunbox = (int)ibox; // アンボクシング
// double iunbox = (double)ibox; // ボクシング前の型と互換性がないためエラー。
}
}