まず、梱包と開梱とは何ですか?
使用します。
元の型 (Sbyte、Byte、Short、Ushort、Int、Uint、Long、Ulong、Char、Float、Double、Bool、Decimal)、列挙 (enum)、構造体 (struct) を含む値の型。
参照型には、クラス、配列、インターフェイス、デリゲート、文字列などが含まれます。スタック上に配置する; 参照型 obj を配置する場合、obj オブジェクトをヒープに配置し、それに temp 値を割り当てる必要があります。この一連のプロセスがボックス化プロセスです。
アンボックス化: 参照型から任意の値型への明示的な変換。ボックス化とは異なり、ボックス化を解除すると変形が表示されます。
暗黙的な変換は常に成功し、例外はスローされません:
(1)、派生クラスから基本クラスへ;
(3)、クラスからインターフェースへインターフェース);
(4)、Null から任意のクラスへ;
明示的な参照変換、以下は例外をスローする可能性があり、変換は成功しない可能性があります:
、(2)、インターフェイスからインターフェイスへ (基本インターフェイスから派生インターフェイスへ、または 2 つのインターフェイスに関係がありません)
、 (3)、インターフェイスからクラスへ (クラスがインターフェイスを実装しているか、クラスが閉じられていません)
、 (4)、クラスからインターフェイス (クラスはインターフェイスを実装しておらず、クラスは閉じられていません);
ボックス化とボックス化の定義は上で簡単に説明しました
開梱の定義ヒープとスタックでボックス化とボックス化を使用する方法について簡単に説明します。宣言自体は、定義されたスコープを超える限り、初期化プロセスです。メモリは自動的に解放されます。Java と同様に、参照型はヒープにメモリを割り当て、そのマネージド ヒープはガベージ コレクションを実行します。ボックス化/アンボックス化は、2 つのデータ型が変換されるときに発生します。
ボックス化とアンボックス化の長所と短所を比較します
ボックス化とアンボックス化は 2 つのタイプ間の変換を満たしますが。ただし、ボックス化プロセスから、サイズが特に大きい場合、新しいオブジェクトをヒープに追加する必要があることは、プログラムの効率に確実に大きく影響することがわかります。物事には常に裏表があり、どんな剣にも裏表があり、物事はシンプルになり、パフォーマンスは低下します。したがって、アプリケーションではボックス化操作を避けるように努める必要があります。 ️ボックス化とボックス化解除の操作を理解すると、ボックス化操作によりデータがヒープとスタックにコピーされ、ボックス化操作が頻繁に行われるとパフォーマンスが低下することが明確に理解できます。それに比べて、開梱プロセスによって生じるパフォーマンスの損失は比較的小さいです。
梱包と開梱の詳細な手順
1. 箱詰めの詳細な手順:
(1) ヒープ上にメモリ領域を割り当てます。そのサイズは、ボックス化する必要がある値型オブジェクトのサイズに、両方の参照型オブジェクト (型オブジェクト ポインターと同期ブロック参照) が所有するメンバーを加えたサイズに等しくなります。
(2) スタック上の値型オブジェクトを、ヒープ上に新たに割り当てたオブジェクトにコピーします。
(3) ヒープ上の新しいオブジェクトへの参照を返し、スタック上のボックス化された値型オブジェクトに格納します。
このステップでは、プログラマーが自分で記述する必要はありません。ボックス化が発生する場合は、コンパイラーが上記の機能を実行するための IL コードを自動的に追加します。
いわゆるアンボックス化はボックス化に対応する概念ですが、アンボックス化とボックス化のプロセスは逆ではありません:
2. アンボックス化の詳細な手順(unbox.any)
アンボックス化するオブジェクトが null の場合、Throws NullReferenceException。
参照によって予期されるオブジェクトではないボックス化されたオブジェクトを指すと、InvalidCastException がスローされます。
- ボックス化されたオブジェクトの各フィールドのアドレスを取得するこのプロセスは「ボックス化解除」です
通常、ボックス化解除にはオブジェクトのコピーが伴いますが、コピー操作はボックス化解除の範囲ではないことに注意してください。
以下は、ボックス化とボックス化解除とは何か、および頻繁なボックス化によるメモリの消費を避ける方法を示す 2 つの小さな例です
(1)、ボックス化:
using System; public class Test { public static void Main(String[] args) { int i = 10; //将值类型的i装箱 //需要注意的是:这里的装箱采用的是值的拷贝 object obj = i; //检验是否装箱成功了 if(obj is int) { Console.WriteLine("数据已经装箱!"); } //我们在这里更改i的值 i = 33; Console.WriteLine("int i现在的值是:{0}",i); Console.WriteLine("int i装箱的值是:{0}",obj); } }
(2)、ボックスの開梱:
int i = 10; object obj = i; int j = (int)obj; (3)、避免频繁的装箱: int i = 10; int j = 20; int s = 30; Console.WriteLine("i的值为{0},j的值为{1},s的值为{2}", i.ToString(), j.ToString(), s.ToString());
上記は C# のボックス化とアンボックス化の概要であり、その考え方は非常に明確で、ボックス化とアンボックス化の長所と短所、ボックス化とアンボックス化の手順など、非常に包括的な内容です。初心者が学ぶのに適しています。
C# のボクシングとアンボクシングを簡単に学習することに関するその他の記事については、PHP 中国語 Web サイトに注目してください。