次の方法で共有


ジェネリック メソッド (C# プログラミング ガイド)

ジェネリック メソッドは、次のように型パラメーターを使用して宣言されるメソッドです。

static void Swap<T>(ref T lhs, ref T rhs)
{
    T temp;
    temp = lhs;
    lhs = rhs;
    rhs = temp;
}

次のコード例は、型引数に int を使用してメソッドを呼び出す方法の 1 つを示しています。

public static void TestSwap()
{
    int a = 1;
    int b = 2;

    Swap<int>(ref a, ref b);
    System.Console.WriteLine(a + " " + b);
}

型引数を省略して、コンパイラが推論することもできます。 次の Swap の呼び出しは、前の呼び出しと同じです。

Swap(ref a, ref b);

型推論の同じ規則が静的メソッドとインスタンス メソッドに適用されます。 コンパイラは、渡すメソッド引数に基づいて型パラメーターを推論できます。制約または戻り値からのみ型パラメーターを推論することはできません。 そのため、型推論は、パラメーターのないメソッドでは機能しません。 型推論は、コンパイラがオーバーロードされたメソッド シグネチャの解決を試みる前に、コンパイル時に発生します。 コンパイラは、同じ名前を共有するすべてのジェネリック メソッドに型推論ロジックを適用します。 オーバーロード解決手順では、型推論が成功したジェネリック メソッドのみがコンパイラに含まれます。

ジェネリック クラス内では、非ジェネリック メソッドは次のようにクラス レベルの型パラメーターにアクセスできます。

class SampleClass<T>
{
    void Swap(ref T lhs, ref T rhs) { }
}

包含クラスと同じ型パラメーターを受け取るジェネリック メソッドを定義すると、コンパイラは警告 CS0693 を生成します。これは、メソッド スコープ内で、内部 T に指定された引数によって外部 Tに指定された引数が非表示になるためです。 クラスのインスタンス化時に指定された型引数以外の型引数を使用してジェネリック クラス メソッドを柔軟に呼び出す必要がある場合は、次の例の GenericList2<T> に示すように、メソッドの型パラメーターに別の識別子を指定することを検討してください。

class GenericList<T>
{
    // CS0693.
    void SampleMethod<T>() { }
}

class GenericList2<T>
{
    // No warning.
    void SampleMethod<U>() { }
}

制約を使用して、メソッドの型パラメーターに対してより特殊な操作を有効にします。 Swap<T>という名前のこのバージョンのSwapIfGreater<T>は、IComparable<T>を実装する型引数でのみ使用できます。

void SwapIfGreater<T>(ref T lhs, ref T rhs) where T : System.IComparable<T>
{
    T temp;
    if (lhs.CompareTo(rhs) > 0)
    {
        temp = lhs;
        lhs = rhs;
        rhs = temp;
    }
}

ジェネリック メソッドは、複数の型パラメーターでオーバーロードできます。 たとえば、次のメソッドはすべて同じクラスに配置できます。

void DoWork() { }
void DoWork<T>() { }
void DoWork<T, U>() { }

メソッドの戻り値の型として型パラメーターを使用することもできます。 次のコード例は、 T型の配列を返すメソッドを示しています。

T[] Swap<T>(T a, T b)
{
    return [b, a];
}

C# 言語仕様

詳細については、C# 言語仕様のを参照してください。

こちらも参照ください