ボクシング/アンボクシングと型キャストの違いは何ですか?
多くの場合、これらの用語は同じ意味で使用されているようです。
ボクシングとは、null許容値ではない型を参照型に変換すること、または値型を実装するインターフェイス(たとえば)に変換することをint
指しますIComparable<int>
。さらに、基になる値型からnull許容型への変換もボクシング変換です。(警告:この主題に関するほとんどの議論は、後者の2つのタイプの変換を無視します。)
例えば、
int i = 5;
object o = i;
i
タイプのインスタンスに変換しますobject
。
アンボックス化とは、null許容値ではない型のインスタンスからの明示的な変換、object
つまりValueType
、インターフェイス型からnull許容値ではない型(たとえば、 )IComparable<int>
への変換を指しますint
。さらに、null許容型から基になる型への変換も開開変換です。(警告:この主題に関するほとんどの議論は、後者の2つのタイプの変換を無視します。)
例えば、
object o = (int)5;
int i = (int)o;
o
ボックス化された整数をタイプのインスタンスに変換しますint
。
型キャストは、式を特定の型に明示的に変換することです。したがって
(type) expression
expression
タイプのオブジェクトに明示的に変換しますtype
。
ボクシングとアンボクシングは型キャストのサブセットです。ボクシングは、値型を参照型として扱う行為です(実際には、その値型の内容を(スタックから)ヒープにコピーし、そのオブジェクトへの参照を返す必要があります)。これにより、互換性のある参照型が予想される場所に値型を渡すことができます。また、仮想メソッド呼び出しや参照型の他の機能を値型で実行することもできます。ボックス化解除は、この操作の逆です(ボックス化されたオブジェクトから値型を取得します)。
型キャストは、特定の型の変数から別の変数へのあらゆる型変換に使用される用語です。それはより広い概念です。
数分前、私はこの違いをカバーする関連する質問に答えました。要約すると、C#キャスト演算子によって生成されたさまざまなタイプのIL命令を分類しました。
box
IL命令)とアンボクシング(unbox
IL命令)dynamic_cast<Type>
C ++の場合と同様に、castclass
IL命令を使用して検証します)static_cast<Type>
に、プリミティブ型間のさまざまなタイプのキャスト用のIL命令がたくさんあります)op_XXX
メソッドへのメソッド呼び出しにすぎません)。ボックス化は、値型(int、double、float、Guidなど)を参照型(System.Object、System.Stringなど)に変換するための用語です。このボクシング操作を実行すると、ヒープにメモリが割り当てられます(ガベージコレクターは最終的にこれを再利用する必要があります)。ボックス化解除はこのプロセスの逆であり、参照型を取得して値型に変換します。
キャストとは、型(たとえば、System.Object)を取得し、それを別の型(たとえば、System.String)として扱うことです。
C#で何かをボックス化すると、それを別のタイプにキャストすることになります。違いは、新しい参照型が作成されるときに追加のメモリを割り当てることです。
結論:ボクシングは、値型を参照型に変換する特殊な種類のキャストであり、新しい参照型の割り当てが必要です。
ボクシング/アンボクシングと型キャストは2つの異なる操作ですが、同じ構文を使用します。
それらは、それについて話している人が実際に何が起こっているのかわからない場合にのみ交換可能に使用されます...
ボックス化とは、値型をオブジェクトとしてヒープに格納することであり、ボックス化解除とは、オブジェクトから値を読み取ることです。正確なタイプであるため、値のボックスを解除することしかできません。
キャストとは、基本タイプを別の基本タイプに変換するとき(からint
)long
、または参照のタイプを変更するとき(からからなどList<int>
)IEnumerable<int>
です。
ボックス化とは、値型の変数 (つまり、整数) を参照型に変換することです。ボックス化解除はその逆で、型キャストを使用します。.NET の世界では、すべてが「オブジェクト」型から派生します。
例 (C# の例):
int myInt = 0; // original variable (unboxed to begin with)
object boxed = myInt; // box it up
int myIntUnBoxed = (int)boxed; // and unbox it again using type casting
ここから得られるのは、型システムの統一であり、値型を参照型として扱うことができます。この記事では、ボックス化/ボックス化解除について詳しく説明します。
ボクシング (暗黙的)
int 番号 = 12;
オブジェクト ボックス = 番号;
アンボックス (明示的)
オブジェクト ボックス = 12;
int 番号 = (int)box;