私は物事をクリアしようとしましょう...
ジェネリックは、メタデータのパラメーターと制約を含む IL として保存されます。ジェネリック型も型であり、実行時にランタイム型に変換されます。これは、テンプレート型が存在せず、派生型のみが存在する C++ との主な違いです。C# では、ジェネリック型は DLL に存在しますが、派生型は (実行時に作成されるまで) 存在しません。
ただし、コンパイラが行うことはいくつかあります。たとえば、List.Add(T) がある場合、IL の署名はまさにそれです。ただし、呼び出すと、List.Add(Foo) をメソッドとして使用してメソッドを解決します。たとえば、IL では次のように表示されます (フィールドをロードする場合):
ldfld class [mscorlib]System.List`1<Foo> Bar::variable
「T」ではなく「Foo」がここにあることに注意してください。
また、ジェネリック定義で T に制約を設定すると、コンパイル時にメタデータに対してチェックされます。
この時点で、まったく異なるが関連するものを指摘したいと思います。C# は、(一般的に) 型を遅延生成することでパフォーマンスを向上させます。これも C++ とは大きく異なります。静的コンストラクターとそれらが呼び出されたときに実験すると、これが実際に動作していることがわかります。