原則として:
1. C++ テンプレートと同様に、C# のジェネリックスの本質は型の型です。
これは型を定義し、そのインスタンス化された各オブジェクトは特定の型であるため、型の型と呼ばれます。
2. インスタンス化すると、次の 2 つの状況に分けられます。
参照型と値型
参照型は本質的にポインタ、つまりメモリ アドレスであるため、ポインタ変数によって使用されるバイト数は、特定のビット長のマシンでは同じです。たとえば、32 ビット マシンでは 4 バイトが使用されます。
ジェネリックスの本質は、定義された型の一種であり、コンパイル後、この型定義の特性を記述するバイナリ コードがメモリに保存されます。
ここでは、まず、ソース コードのコンパイル後にインスタンス化されたオブジェクトの型定義とメモリ割り当てについて説明します。ソース コードがコンパイルされた後、実行中にプログラム ファイル (exe ファイルなど) をプログラムしてメモリ空間にロードする必要があります (最新の OS)。マッピングを使用し、論理的にメモリを占有し、物理的にページング方式を使用し、データのどの部分を物理メモリに転送するかを使用します。
クラスを定義する場合、コンパイル後のクラスの説明 (どのデータ メンバー、どのメンバー関数、それぞれの権限などに関する情報) が exe ファイルの一部を形成し、実行後にメモリにロードされます。メモリのアドレスは 0x0001 にバイナリデータが設定されます。
クラス オブジェクトをインスタンス化する場合、言語によって異なります。C++ では、クラスのインスタンス化オブジェクトはスタック上にメモリを割り当てます。C# では、クラスのインスタンス化オブジェクトはヒープ上にメモリを割り当てます。メモリ空間のこの部分はプログラムのメモリ内にあります。 (Windows 32 ビット システムなど、プログラムのメモリ空間は 4G)プロセスへ。
同様に、汎用のエンコードされたバイナリ データは exe ファイルに含まれており、メモリにロードされます。
ジェネリックがインスタンス化されるとき、つまり特定の型がコンパイルされるとき (C# でジェネリックをインスタンス化するプロセスはコンパイル中に実行されることに注意してください。つまり、インスタンス化されたジェネリックがコードで使用されます。特定の型ごとに、バイナリが使用されます)コードはコンパイル中に生成され、ジェネリック自体のバイナリ コードが exe ファイルに書き込まれます) インスタンス化された各型のバイナリ コードが exe ファイル内で占める必要があるスペースはどれくらいですか?
C# では、参照型と値型を区別する必要があります。プログラムのソース コード内で、ジェネリックが 2 つの参照型と 2 つの値型をインスタンス化するとします。
次に、参照型については次のようになります。
1 つは 4 バイトのポインターを使用し、2 つは 2 つのポインターを使用します。バイナリ データは、使用される型 (vector<myClass> の myClass など) を指します。myClass は定義されたクラス型です。コンパイル後、バイナリ データは exe ファイルに保存されます。 ) (相対アドレスはメモリにロードされた後にメモリアドレスに変換されます) これは、参照型のインスタンス化されたオブジェクトがヒープ上に配置され、実行時にポインタからバイナリアドレスが取得されるためです。 myClass 型で記述されたデータを取得し、インスタンス化されたオブジェクトが占めるメモリ領域を計算し、ヒープ上に割り当てます。
値の型の場合:
値の型には、構造体と事前定義されたデータ型が含まれます (vector<int>、vector<double> など) ジェネリックスをインスタンス化すると、インスタンス化時に 2 つのクラスの実際のバイナリ データがそれらを表すために生成されます。それらのオブジェクトをプログラム内に書き込むと高速になります(もちろん、参照のように実行時に計算してエンコードすることもできます)が、値の型がスタック上に割り当てられるため、効率を得るために柔軟性が失われるため、実行しますこのような)