ジェネリックの概要 (C# プログラミング ガイド)
ジェネリック クラスとジェネリック メソッドは、それぞれの非ジェネリック バージョンでは実現できない形で再利用性、タイプ セーフ、および効率性を兼ね備えています。通常、ジェネリックは、コレクションおよびコレクションに対して動作するメソッドと共に使用されます。Version 2.0 の .NET Framework クラス ライブラリには、System.Collections.Generic という新しい名前空間が用意されています。この名前空間には、ジェネリックベースの新しいコレクション クラスがあります。.NET Framework 2.0 以降を対象にするすべてのアプリケーションでは、ArrayList などの以前の非ジェネリック クラスの代わりに、新しいジェネリック コレクション クラスを使用することをお勧めします。詳細については、「.NET Framework クラス ライブラリのジェネリック (C# プログラミング ガイド)」を参照してください。
また、カスタム ジェネリック型やカスタム ジェネリック メソッドを作成して、独自の汎用ソリューションを提供したり、タイプ セーフで効率的なパターンを設計したりすることもできます。以下のコード例は、簡単な汎用リンク リスト クラスを示しています。通常は、独自のクラスを作成するよりも、.NET Framework クラス ライブラリに用意されている List<T> クラスを使用してください。この例では、通常、具体的な型を使用して、リストに格納する項目の型を示すところで、型パラメーター T を使用しています。このパラメーターは、次のように使用されています。
AddHead メソッドのメソッド パラメーターの型として使用されています。
GetNext パブリック メソッドの戻り値の型、および入れ子にされた Node クラスの Data プロパティとして使用されています。
入れ子になったクラスのプライベート メンバー データの型として使用されています。
T は、入れ子になった Node クラスで使用できることに注意してください。GenericList<T> を、たとえば、GenericList<int> のように具体的な型でインスタンス化すると、T の各出現箇所は、int に置き換えられます。
// type parameter T in angle brackets
public class GenericList<T>
{
// The nested class is also generic on T.
private class Node
{
// T used in non-generic constructor.
public Node(T t)
{
next = null;
data = t;
}
private Node next;
public Node Next
{
get { return next; }
set { next = value; }
}
// T as private member data type.
private T data;
// T as return type of property.
public T Data
{
get { return data; }
set { data = value; }
}
}
private Node head;
// constructor
public GenericList()
{
head = null;
}
// T as method parameter type:
public void AddHead(T t)
{
Node n = new Node(t);
n.Next = head;
head = n;
}
public IEnumerator<T> GetEnumerator()
{
Node current = head;
while (current != null)
{
yield return current.Data;
current = current.Next;
}
}
}
次のコード例は、クライアント コードで GenericList<T> ジェネリック クラスを使用して整数のリストを作成する方法を示しています。このコードの型引数を変更するだけで、文字列や他の任意のカスタム型のリストを生成するように簡単に修正できます。
class TestGenericList
{
static void Main()
{
// int is the type argument
GenericList<int> list = new GenericList<int>();
for (int x = 0; x < 10; x++)
{
list.AddHead(x);
}
foreach (int i in list)
{
System.Console.Write(i + " ");
}
System.Console.WriteLine("\nDone");
}
}