導入
ジェネリクスは「どんな型でもOK」ですが、時には「比較できる型だけ」「特定のインターフェースを実装した型だけ」に制限したくなります。それがwhereによる型制約です。
図解
flowchart LR
G["Max<T> where T : IComparable<T>"] -->|条件| C["「比較できる型」だけ受け付ける"]
C --> OK["int, string, DateTime ✅"]
C -.-> NG["比較できない独自型 ❌"]
サンプル
// where T : IComparable<T> → 「大小比較できる型」に限定
Console.WriteLine(Max(3, 8)); // 8
Console.WriteLine(Max("apple", "box")); // box(辞書順で後)
T Max<T>(T a, T b) where T : IComparable<T>
{
// 制約があるので CompareTo が使えると保証される
return a.CompareTo(b) >= 0 ? a : b;
}
where T : 制約で型パラメータに条件を付けるIComparable<T>制約ならCompareToが使えると保証される- 制約により「その型が持つメソッド」を安全に呼べる
演習
Console.WriteLine(Smaller(5, 2)); // 2
// TODO: 2つの値のうち小さい方を返す Smaller<T> を定義してください
// (where T : IComparable<T> の制約を付ける)
___
- 期待される出力:
2
ヒント1を見る
CompareToが負ならaの方が小さいです
ヒント2を見る
T Smaller<T>(T a, T b) where T : IComparable<T> => a.CompareTo(b) <= 0 ? a : b;
まとめ
where T : 制約で型パラメータに条件を付ける- 制約により、その型のメソッドを安全に呼べる
- 「比較できる型だけ」などの限定に使う
次回: 「並べ替えのルールを渡す」比較子と、型の柔軟さを支える共変・反変です。