C#
 Computer >> コンピューター >  >> プログラミング >> C#

C#のボクシング(Boxing)とアンボクシング(Unboxing)をわかりやすく解説

C#には「値型」と「参照型」という2つの大きな型の分類が存在します。これらの間でデータをやり取りする際に登場するのが、ボクシング(Boxing)アンボクシング(Unboxing)という変換処理です。本記事では、それぞれの仕組みと具体的なコード例を交えて解説します。

ボクシング(Boxing)とは

ボクシングとは、値型(int、double、structなど)を暗黙的に参照型(objectなど)へ変換する処理です。値型の変数をobject型の変数に代入すると、その値はヒープ上に新しいオブジェクトとして確保され、そこにコピーされます。

この変換は明示的なキャストを必要としないため、「暗黙的」な変換と呼ばれます。

アンボクシング(Unboxing)とは

アンボクシングとは、ボクシングによって作成された参照型のオブジェクトを、元の値型へ明示的に戻す変換処理です。ボクシングとは異なり、キャスト演算子を使った明示的な型指定が必須となります。

なお、アンボクシング時に対象のオブジェクトが指定した値型と一致しない場合、InvalidCastExceptionがスローされる点に注意が必要です。

基本的なコード例

まずは最もシンプルなint型を使った例を見てみましょう。

// 値型 int の宣言
int myVal = 12;

// ボクシング:値型 → 参照型(object)への暗黙的な変換
object myBoxed = myVal;

// アンボクシング:参照型 → 値型への明示的な変換
int myUnBoxed = (int)myBoxed;

このコードでは、myValという値型の変数がmyBoxedに代入される際にボクシングが発生し、(int)によるキャストでアンボクシングが行われています。

ArrayListでのボクシング・アンボクシングの例

非ジェネリックのコレクションであるArrayListは、要素をすべてobjectとして扱うため、値型を格納するとボクシングが発生します。以下に具体例を示します。

int a = 5;
ArrayList arr = new ArrayList();

// ボクシング:int型の a が object として格納される
arr.Add(a);

// アンボクシング:object を int 型へ明示的にキャスト
int b = (int)arr[0];

arr.Add(a)の時点でint型の値がobject型にボクシングされ、取り出す際に(int)でアンボクシングしています。

パフォーマンスに関する注意点

ボクシングとアンボクシングは便利な仕組みですが、ヒープへのメモリ割り当てやガベージコレクションの負荷を伴うため、頻繁に行うとパフォーマンス低下の原因になります。

そのため、C# 2.0以降では、ボクシングを回避できるジェネリックコレクション(List<T>など)を使用することが推奨されています。上記のArrayListの例も、List<int>を使えばボクシングなしで同じ処理を実現できます。

  1. C++で円と長方形の重なりを判定するアルゴリズム

    問題の概要円を (radius, xc, yc) という形式で表します。ここで (xc, yc) は円の中心座標です。同様に、軸に平行な長方形(軸平行境界ボックス)を (x1, y1, x2, y2) という形式で表し、(x1, y1) が左下隅の座標、(x2, y2) が右上隅の座標とします。このとき、円と長方形が互いに重なっているかどうかを判定する必要があります。たとえば、次のような入力が与えられた場合を考えてみましょう。この場合、出力は true(重なりあり)となります。解決のアプローチこの問題を解く鍵は、「長方形の中で円の中心に最も近い点」を見つけることです。その点と円の中心との距離が

  2. C++で解くドミノとトロミノを使ったタイル敷き詰め問題(2×Nボード)

    問題の概要本記事では、「ドミノ」と「トロミノ」という2種類の形状を使ったタイル敷き詰め(タイリング)問題をC++で解く方法を解説します。これらのピースは、以下のように回転させて使用することができます。タイリングでは、盤面上のすべてのマスを必ずタイルで覆わなければなりません。また、2つのタイリング方法は、盤上の4方向に隣接する2つのセルにおいて、片方のタイリングだけがその両方のマスを同じタイルで占有している場合に限り「異なる」とみなされます。入力と出力の例整数Nが与えられたとき、2×Nのボードを敷き詰める方法が何通りあるかを求めます。例えば、入力が3の場合、出力は5となります。敷き詰め方は以下の