ジェネリクスとは
ジェネリクスを使うと、扱う型を後から指定できるクラスやメソッドを定義できます。objectへの変換やキャストを減らし、コンパイル時の型チェックを利用できます。
static T First<T>(T[] values)
{
return values[0];
}
int number = First(new[] { 10, 20, 30 });
string word = First(new[] { "C#", "Rust" });
Tが型パラメーターです。呼び出し時に引数から型を推論できる場合、型引数を省略できます。
制約
where句で型パラメーターに制約を付けられます。たとえばwhere T : classは参照型に限定し、where T : new()は引数なしコンストラクタを要求します。
標準コレクションとの関係
List<T>やDictionary<TKey, TValue>もジェネリクスを使っています。要素の型が明確になるため、誤った型の値を追加しようとするとコンパイル時に検出できます。
ジェネリクスは、必要以上に複雑な抽象化を作るためではなく、共通する処理を型安全に再利用するために使います。