ジェネリックとはアルゴリズムの再利用を可能とする機能で、C++のテンプレートに代わるものです。C++ テンプレートと C# ジェネリックの違い | MSDN
ジェネリックは、おもにコレクションで利用されています。
class MyClass <T> { }ジェネリック クラス - C# プログラミング ガイド | Microsoft Learn
void Method<T>(T val) { }ジェネリック メソッド - C# プログラミング ガイド | Microsoft Learn
共変性と反変性 (C#) | Microsoft Learn
型パラメータが反変 (contravariance) であることを示し、指定の型よりも弱い派生型を使用できるようになります。in (ジェネリック修飾子) - C# リファレンス | Microsoft Learn
interface Sample<in A> {}
型パラメータが共変 (covariance) であることを示し、指定の型よりも強い派生型を使用できるようになります。out キーワード (ジェネリック修飾子) - C# リファレンス | Microsoft Learn
interface Sample<out A> {}
型パラメータに指定できる型を、制約できます。たとえば次のようにクラスが定義されていると、
class A { } class B : A { } class X { } class MyClass1<T> { } // 制約なし class MyClass2<T> where T : A { } // Aを継承するクラスを指定するように要求
これを用いる側は指定されたクラスを継承するか、そのインターフェイスを実装する型を指定する必要があります。
new MyClass1<A>();
new MyClass1<B>();
new MyClass1<X>();
new MyClass2<A>();
new MyClass2<B>();
new MyClass2<X>(); // error CS0311: 型 'X' はジェネリック型またはメソッド 'MyClass2<T>' 内で型パラメーター 'T' として使用できません。'X' から 'A' への暗黙的な参照変換がありません。
制約する型として"class"や"struct"を指定できます。また制約が複数ある場合には、それらを続けて記述します。
class MyClass<T, U> where T : class where U : struct { }
型パラメータに指定された型は、typeof()で取得できます。c# - How to get the type of T from a member of a generic class or method - Stack Overflow
void Method<T>(T val) { Type type = typeof(T); }