佐々木屋

技術的なことから趣味まで色々書きます

ボックス化って何?

型変換でよく出てくる用語の一つに「ボックス化(又はボクシング)」があります。よくボックス化はコストがかかるとか言われますが、一体何の意味か分かりますか?

値型を参照型に変換する行為

簡単に言うとそういうことです。例えばint型をobject型に変換することを「ボックス化」と呼ぶわけです。ただこれは少し乱暴な表現で、冷静に考えればint型は値型でobject型は参照型なので型変換が必要なはずです。なぜ型変換せず変換できるのでしょうか。

int n = 10;
object o = n;
Dim n As Integer = 10
Dim o As Object = n

実はint型はobject型の派生なのです。int型に限らず値型はobject型の派生なので、型変換無しでボックス化が暗黙的に(CLRが)行われます。よって我々が意識することはなく内部で自動的に行われますので、気が付かずにボックス化しているなんてことも起こりえます。

ボックス化の逆は明示的に型変換が必要

ボックス化の逆を「ボックス化解除(又はアンボクシング)」と言います。オブジェクトから値型を抽出する行為です。これはボックス化と異なり、型変換を明示的に行う必要があります。なお、Javaの場合はオートボクシング機能がありますので、この部分のみC#Javaでボックス化のニュアンスが異なりますので注意して下さい。

int n = 10;
object o = n;

o = 20;
n = (int) o;
Dim n As Integer = 10
Dim o As Object = n

o = 20
n = CType(o, Integer)


ボックス化(ボックス化解除)はコストがかかります

値型はスタック領域に書かれますが、参照型はヒープ領域に書かれます。当然スタック領域に比べてヒープ領域の方が速度が遅めですので、そこの変換作業によってコストがかかるということになります。

ボックス化

スタック上の値がヒープ上の新しい領域に値が作成され、その参照情報がスタック領域の新しい場所へ格納されます。
f:id:sasaki816:20190302195500j:plain

ボックス化解除

ヒープ領域に作成したボックス化情報を型変換すると、スタック上に新たな領域を確保して値を作成します。
f:id:sasaki816:20190302195529j:plain


厳密に型を指定して宣言した方がよい、というのは不用意なボックス化を防ぐ意味でもあります。