ジェネリクス
スポンサーリンク
ジェネリックメソッド
次の Swap メソッドは,任意のデータ型について使うことはできません。
例えば,この Swap メソッドは文字列型について値を交換することはできません。
static void Swap(ref double a, ref double b)
{
double temp = a;
a = b;
b = a;
}
次の Swap<T> メソッドは,任意のデータ型について値の交換ができるようにしたものです。
このように,型パラメータ T を持ったクラスやメソッドを,ジェネリクス (generics) といいます。
static void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = a;
}
static void Main()
{
int m = 1, n = 2;
Swap<int>(ref m, ref n);
}
型パラメータ T は,メソッド名の直後に Swap<T> のように書きます。
型パラメータが複数必要であれば,Swap<T, U> のように書けばいいです。
ジェネリックメソッドの呼び出しは,Swap<int>(ref m, ref n) のように書きます。
ただし,引数から型の特定が可能な場合は,Swap(ref m, ref n) のように省略していいです。
ジェネリッククラス
次のプログラムは,スタックを実現する Stack<T> クラスを定義したものです。
ジェネリッククラスについては,型の指定 (<int> など) を省略することはできません。
using System;
class Stack<T>
{
private T[] stack = new T[256];
private int index = 0;
public void Push(T item) { stack[index++] = item; }
public T Pop() { return stack[--index]; }
}
class Program
{
static void Main()
{
Stack<int> stack = new Stack<int>();
stack.Push(123);
stack.Pop();
}
}
型制約
2 引数のうち最大のものを返すジェネリックメソッド Max<T> は次のように書けそうですが,実際にはコンパイルエラーとなります。
// コンパイル不可
// a > b ならば a,そうでなければ b を返す
static T Max<T>(T a, T b)
{
return a > b ? a : b;
}
コンパイルエラーは,型 T に比較用の演算子 > が定義されていないためです。
次のように where 句によって型 T に制約を与えると,型 T は IComparable インタフェースを実装した型のみが許されます。
ICompareble インタフェースには比較を行う CompareTo メソッドが含まれるので,a.CompareTo(b) と書けば a と b の比較が可能となります。
static T Max<T>(T a, T b)
where T : IComparable
{
return a.CompareTo(b) ? a : b;
}
スポンサーリンク