C# ジェネリックメソッドの作成

ジェネリックメソッドは、クラス全体ではなくメソッド単位で型パラメータを持つ機能です。非ジェネリッククラスの中にも定義でき、柔軟な設計が可能になります。

基本的な定義方法

メソッド名の後に <T> を付けることで、ジェネリックメソッドになります。

public static T GetFirst&lt;T&gt;(T[] array)
{
    if (array.Length == 0)
        throw new ArgumentException("配列が空です");
    return array[0];
}

呼び出し方

型引数を明示的に指定する方法と、型推論に任せる方法があります。

int[] numbers = { 1, 2, 3 };
string[] words = { "apple", "banana" };

// 型引数を明示的に指定
int firstNumber = GetFirst&lt;int&gt;(numbers);

// 型推論に任せる(引数から推論される)
string firstWord = GetFirst(words);

引数の型から T が推論できる場合は、型引数を省略できます。

複数の型パラメータを持つメソッド

型パラメータは複数指定できます。

public static TOutput Convert&lt;TInput, TOutput&gt;(
    TInput input, 
    Func&lt;TInput, TOutput&gt; converter)
{
    return converter(input);
}
// int を string に変換
string result = Convert(42, n =&gt; n.ToString());
Console.WriteLine(result); // "42"

// string を int に変換
int number = Convert("123", s =&gt; int.Parse(s));
Console.WriteLine(number); // 123

実用的な例:要素の入れ替え

2つの変数の値を入れ替えるメソッドは、ジェネリックメソッドの典型的な例です。

public static void Swap&lt;T&gt;(ref T a, ref T b)
{
    T temp = a;
    a = b;
    b = temp;
}
int x = 10, y = 20;
Swap(ref x, ref y);
Console.WriteLine($"x={x}, y={y}"); // x=20, y=10

string s1 = "Hello", s2 = "World";
Swap(ref s1, ref s2);
Console.WriteLine($"s1={s1}, s2={s2}"); // s1=World, s2=Hello

ジェネリッククラス内のジェネリックメソッド

ジェネリッククラスの中に、さらに独自の型パラメータを持つメソッドを定義することもできます。

public class Container&lt;T&gt;
{
    private T _value;

    public Container(T value) =&gt; _value = value;

    // クラスの T とは別の型パラメータ U を持つ
    public U Transform&lt;U&gt;(Func&lt;T, U&gt; transformer)
    {
        return transformer(_value);
    }
}
var container = new Container&lt;int&gt;(42);

// int から string への変換
string text = container.Transform(n =&gt; $"値は {n} です");
Console.WriteLine(text); // 値は 42 です
ジェネリッククラス

クラス全体で共通の型パラメータを使用

ジェネリックメソッド

メソッドごとに独立した型パラメータを持てる

ジェネリックメソッドは、LINQ のメソッド(SelectWhere など)の内部でも使われています。型安全でありながら、様々な型に対応できる柔軟なメソッドを作成する際に活用してください。