本文へスキップ
BecomeCoder

C#オブジェクト指向コース · 第5章 オブジェクト指向の実践テクニック · レッスン36

ジェネリックメソッドと型推論

ブラウザで完結

導入

ジェネリクスはクラスだけでなくメソッド単位でも使えます。「どんな型の配列でも先頭を返す」ような処理を、型ごとに書かずに1つで済ませられます。しかも多くの場合、型は推論されるので <T> を書く必要すらありません。

サンプル

// <T> はメソッド呼び出し時に決まる型パラメータ
T First<T>(T[] items) => items[0];

Console.WriteLine(First(new[] { 3, 1, 2 }));      // 3(T は int と推論される)
Console.WriteLine(First(new[] { "x", "y" }));     // x(T は string)

// 2つの型パラメータも書ける
TResult Convert<TInput, TResult>(TInput value, Func<TInput, TResult> f) => f(value);
Console.WriteLine(Convert(5, n => n * 2));        // 10
  • メソッド名<T>(...) で、メソッドごとに型パラメータを持てる
  • 引数から型が分かるときは <T> を省略できる(型推論)
  • LINQ の Select などもジェネリックメソッド

やってみよう

First に空でない double[] を渡したり、Convert の変換ラムダを n => n.ToString() に変えたりして、推論される型が変わる様子を確かめましょう。

演習

T Last<T>(T[] items) => items[items.Length - 1];

// TODO: ジェネリックメソッド Last を使って {10, 20, 30} の末尾を出力してください
Console.WriteLine(___);   // 30
  • 期待される出力: 30
ヒント1を見る

Last(new[] { 10, 20, 30 }) と書けば T は int と推論されます

ヒント2を見る

型を明示するなら Last<int>(...) ですが、通常は省略できます

まとめ

  • ジェネリックメソッドは「メソッド単位で型を抽象化」する
  • 引数から型が分かれば <T> を省略できる(型推論)
  • 標準ライブラリの多くのメソッドがこの形

次回: 自作の型に「比較」と「等価」のルールを持たせます。

実際に動かしてみよう

本文のサンプルや演習のコードは、コードブロック右上の「コピー」ボタンでコピーして、下のエディタに貼り付ければそのまま実行できます。

C# — ブラウザ内で実行

ブラウザ内でC#を動かす環境を読み込みます(初回のみ数秒)。
スクロールして表示された時点でも自動で読み込まれます。