導入
List<int>とList<string>——同じListが、中身の型を変えて使えます。これはジェネリクス(型のパラメータ化)のおかげです。「型を後から指定できる部品」を作れると、同じロジックをあらゆる型で再利用できます。
図解
flowchart LR
G["Box<T><br/>(T は後で決める型)"] --> I["Box<int><br/>整数の箱"]
G --> S["Box<string><br/>文字列の箱"]
style G fill:#e1f5fe
サンプル
// <T> は「使うときに決まる型」。int でも string でも同じコードで動く
var intBox = new Box<int>(42);
Console.WriteLine(intBox.Value); // 42
var strBox = new Box<string>("hello");
Console.WriteLine(strBox.Value); // hello
class Box<T> // T は型パラメータ
{
public T Value { get; }
public Box(T value) => Value = value;
}
クラス<T>のTは「使うときに決まる型」(型パラメータ)Box<int>,Box<string>のように、1つの定義をあらゆる型で使い回せる- 型安全を保ったまま再利用できる(
objectで持つより安全)
演習
var pair = new Pair<string, int>("age", 20);
Console.WriteLine($"{pair.First}: {pair.Second}"); // age: 20
// TODO: 2つの型パラメータ First(T1) と Second(T2) を持つ Pair<T1, T2> を定義してください
___
- 期待される出力:
age: 20
ヒント1を見る
class Pair<T1, T2> { public T1 First { get; } public T2 Second { get; } public Pair(T1 first, T2 second) { First = first; Second = second; } }
ヒント2を見る
型パラメータはカンマ区切りで複数書けます
まとめ
- ジェネリクスは「型を後から指定できる部品」を作る
<T>で型をパラメータ化し、あらゆる型で再利用List<T>など標準ライブラリの主役はほぼジェネリクス
次回: 型パラメータに条件を付ける「型制約」です。