ボクシングやunboxingとジェネリック医薬品
質問
きます。純1.0を収集整数(例えば)でした:
ArrayList list = new ArrayList();
list.Add(i); /* boxing */
int j = (int)list[0]; /* unboxing */
の罰則を使用することではなくタイプ安全性とパフォーマンスによるボクシングやunboxing.
きます。純2.0方法は、ジェネリック医薬品:
List<int> list = new List<int>();
list.Add(i);
int j = list[0];
価格のボクシング(私の理解に必要なオブジェクトを作成し、ヒープにコピーするスタックに割り当て数の整数のオブジェクトおよびその逆のためのunboxing.
どのような用のジェネリック医薬品のメリットを克服す。のスタックに割り当てられた整数のスタックは、見るからにヒープ(私の場合はこの限りではありませんので何が起こる時までの範囲)?そのようなアクセスにはログインが必要のコピーなどのスタックです。
食品をもっと勉強すべきだと思いいますか?
解決
は、ジェネリック医薬品は、それが可能内部で実際T[]
アレイを利用することにより、アンボクシング/ボクシングを避けるようにします。例えばList<T>
は、その内容を格納するT[]
アレイを使用します。
アレイは、もちろん、参照型であり、ヒープに格納されている(CLRの現在のバージョン、云々の矢田に)ことです。しかし、それはT[]
なくobject[]
なので、配列の要素が「直接」保存することができます。つまり、彼らはヒープに残っているが、彼らは、ヒープの上にいる、アレイ内のの代わりに箱詰めされ、アレイは、ボックスへの参照を含んでいる。
はそうList<int>
のために、たとえば、あなたは、このような配列だろう「見た目」に何を持っていると思います
[ 1 2 3 ]このような
ArrayList
を使用していますobject[]
、これを比較してしまうので、「見て」何かます:
[ *a *b *c ]
...どこ*a
などはオブジェクトへの参照(箱入り整数)次のとおりです:
*a -> 1 *b -> 2 *c -> 3
これらの粗イラストすみません。うまくいけば、あなたは私が何を意味するか知ってます。
他のヒント
お混乱の結果、誤解の関係との間にスタック、ヒープ変数です。こちらは、正しい考え方です。
- 変数が保存場所にあるタイプです。
- の寿命についての変数は短す。による"短い"ことを意味"までは現在の関数の返す"、"長しいということはある以上とのこと。
- 場合には、変数の参照型の内容の変数への参照を長寿命の保管場所です。場合には、変数値をタイプして内容を変数とする。
として実装の詳細は、保存場所を保証するものではあ短寿命を割り当てることができるスタックです。保管場所をも長期的な割り当てのヒープ.通知することは言うもの"値型を常に割り当てのスタックです。" 値の種類 ない 常に割り当てのスタック:
int[] x = new int[10];
x[1] = 123;
x[1]
貯蔵します。で長寿;このライブより長いことです。そのためにヒープ.ことのでintは関係ありません。
お正確に言うのはなぜ弁当intでは:
価格のボクシングにオブジェクトを作成し、ヒープにコピーするスタックに割り当て数の整数のオブジェクトおよびその逆のためのunboxing.
どこに行くに誤りがとう"と言うことをスタックに割り当てまでの整数.ながの整数値が割り当てられた.そのた保管 含まれている整数, ではなく、を含む への参照ヒープ所在地.の価格は、オブジェクトのコピー;することになりそうのコストと関連がある。
なぜな汎用の変数か?だって可変のタイプTを構築するintしい変数をint型です。変数のint型の収納場所が含まれるint. かを参考として示したもので、これらの場所のスタックのヒープとは全く無関係.何か関係があることを保存場所 を含むint, ではなく、を含む への参照には、ヒープ.以降、貯蔵場所を含むintありませんが、コストボクシングやunboxing:配新しいストレージエディタで開き、ヒープコピーをintに保管します。
することを明らかになりましたが?
ジェネリック医薬品のリストの内部配列を入力 int[]
の代わりに効果的に object[]
, るいはボクシング.
こんなジェネリック医薬品:
- 呼び出す
Add(1)
. - の整数
1
は弁当に、オブジェクトを必要とするための新しいオブジェクトを構築し、ヒープ. - このオブジェクトに渡される
ArrayList.Add()
. - 食のオブジェクトのぬいぐるみに
object[]
.
あるレベルの間接指定はこちら ArrayList
-> object[]
-> object
-> int
.
とジェネリック医薬品:
- 呼び出す
Add(1)
. - のint1に渡され
List<int>.Add()
. - Intがぬいぐるみに
int[]
.
あなただけの二つのレベルの間接指定: List<int>
-> int[]
-> int
.
別の複数の違い:
- の汎用方法のままで合計8 12バイト一つのポインタは、int)の値4/8一つの配分および4のです。これによりアライメントとパディングします。汎用方法にするためには4バイトのスペースの配列になります。
- の汎用方法が必要で配弁当int;汎用のメソッドはいません。この高速化と低減GC解約.
- の汎用方法が必要で鋳出値です。このtypesafe、奥高尾にひっそりと建つ料亭。遅くなります。
るArrayListのみのタイプ object
での使用このクラスが必要で鋳造から object
.の場合の値型では、この鋳造的にボクシングやunboxing.
ご利用の際は汎用のリストをコンパイラの出力専門のコードが値型の 実際の値 が格納されているリストの参照ではなくオブジェクトの値です。そのためのないボクシングが必要です。
価格のボクシング(私の理解に必要なオブジェクトを作成し、ヒープにコピーするスタックに割り当て数の整数のオブジェクトおよびその逆のためのunboxing.
いという思いを大切にしていると仮定値の種類は常にインスタンス化のスタックです。の場合はこの限りではありません-いを作成するには、ヒープのスタックに登録する情報はここをご覧くださいEric Lippertの記事: についての真実価値の種類.
ます。純1、 Add
方法:
- スペースが割り当てられるヒープ;新しい参照は
- の内容
i
変数はコピーを参照 - のコピーを参考までのリストの末尾に
ます。純2:
- のコピーを可変
i
渡されるAdd
方法 - コピーするコピーはリストの末尾に
あり、 i
変数はコピー後、この値型の値型を常にコピーされた場合でも、そういう方法でパラメータがありませんの冗長化コピーのヒープ.
なぜあなたは値\オブジェクトが格納されるWHERE
の観点で考えていますか? C#の値型にどのCLRの選択に応じてヒープと同様にスタック上に格納することができます。
はWHAT
は、コレクションに格納されています。 ArrayList
の場合、コレクションはList<int>
がintの値そのものが含まれているとして、箱入りのオブジェクトへの参照が含まれています。