ジェネリック メソッド (C# プログラミング ガイド)
ジェネリック メソッドは、次のように型パラメーターで宣言されるメソッドです。
static void Swap<T>(ref T lhs, ref T rhs)
{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
メソッドの呼び出し方法の 1 つを示しているのが次のコード サンプルです。型引数に int
を利用します。
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>() { }
}
メソッドの型パラメーターでさらに多くの特殊操作を可能にするために、制約を使用します。 SwapIfGreater<T>
という名前が付けられた Swap<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# 言語の仕様」を参照してください。
関連項目
.NET