.NET Framework のジェネリックの概要
更新 : 2007 年 11 月
ここでは、.NET Framework のジェネリックの概要と、ジェネリック型またはジェネリック メソッドの要約を示します。さらに、ジェネリックに関連した用語を定義します。
ジェネリックの定義と使用
ジェネリックは、格納または使用される 1 つ以上の型のプレースホルダ (型パラメータ) を持つクラス、構造体、インターフェイス、およびメソッドです。ジェネリック コレクション クラスでは、格納されるオブジェクトの型のプレースホルダとして、型パラメータを使用できます。型パラメータは、フィールドの型およびメソッドのパラメータの型として出現します。ジェネリック メソッドでは、戻り値の型と仮パラメータのいずれかの型として型パラメータを使用できます。単純なジェネリック クラスの定義を次のコードに示します。
Public Class Generic(Of T)
Public Field As T
End Class
public class Generic<T>
{
public T Field;
}
generic<typename T> public ref class Generic
{
public:
T Field;
};
ジェネリック クラスのインスタンスを作成するときには、型パラメータと置き換える実際の型を指定します。これにより、型パラメータが出現するすべての場所を選択した型に置き換えた新しいジェネリック クラスが作成されます。これは、構築されたジェネリック クラスと呼ばれます。次のコードに示すように、作成されたクラスは選択した型に適合したタイプ セーフなクラスです。
Dim g As New Generic(Of String)
g.Field = "A string"
Generic<string> g = new Generic<string>();
g.Field = "A string";
Generic<String^>^ g = gcnew Generic<String^>();
g->Field = "A string";
ジェネリックの用語
.NET Framework のジェネリックに関する用語を次に示します。
"ジェネリック型の定義" とは、クラス、構造体、インターフェイスで格納または使用できる型のプレースホルダを使用する、テンプレートとして機能するクラス、構造体、インターフェイスの宣言です。たとえば、Dictionary<TKey, TValue> クラスは、キーと値の 2 つの型を格納できます。ジェネリック型の定義は単なるテンプレートにすぎないため、ジェネリック型の定義であるクラス、構造体、インターフェイスのインスタンスを作成することはできません。
"ジェネリック型パラメータ" (または "型パラメータ") とは、ジェネリック型の定義またはジェネリック メソッドの定義に含まれるプレースホルダです。Dictionary<TKey, TValue> ジェネリック型には、キーと値の型を表す TKey と TValue の 2 つの型パラメータがあります。
"構築ジェネリック型" (または "構築された型") とは、ジェネリック型の定義のジェネリック型パラメータに型を指定することによって作成されたジェネリック型です。
"ジェネリック型引数" とは、ジェネリック型パラメータと置き換えられる任意の型です。
一般用語である「ジェネリック型」には、構築された型とジェネリック型の定義の両方が含まれます。
"制約" とは、ジェネリック型パラメータの制限です。たとえば、型パラメータを IComparer<T> ジェネリック インターフェイスを実装する型に制限することで、型のインスタンスを確実に順序付けることができます。また、型パラメータを特定の基本クラスを持つ型、既定のコンストラクタを持つ型、参照型または値型である型に制約することもできます。ジェネリック型のユーザーは、制約を満たさない型引数を置き換えることはできません。
"ジェネリック メソッドの定義" とは、ジェネリック型パラメータのリストと、仮パラメータのリストの 2 つのパラメータ リストを持つメソッドです。次のコードに示すように、型パラメータは、戻り値の型または仮パラメータの型として出現します。
Function Generic(Of T)(ByVal arg As T) As T Dim temp As T = arg ... End Function
T Generic<T>(T arg) { T temp = arg; ...}
generic<typename T> T Generic(T arg) { T temp = arg; ...};
ジェネリック メソッドは、ジェネリック型または非ジェネリック型で出現できます。メソッドはジェネリック型に属しているだけである、または、型が外側の型のジェネリック パラメータである仮パラメータを持っているだけであるという理由から、メソッドはジェネリックではないという点に注意することが重要です。メソッドがジェネリックになるのは、そのメソッドが独自の型パラメータ リストを持つ場合だけです。次のコードでは、G メソッドだけがジェネリックです。
Class A Function G(Of T)(ByVal arg As T) As T ... End Function End Class Class Generic(Of T) Function M(ByVal arg As T) As T ... End Function End Class
class A { T G<T>(T arg) {...} } class Generic<T> { T M(T arg) {...} }
ref class A { generic<T> T G(T arg) {...}; }; generic<typename T> ref class Generic { T M(T arg) {...}; };
Visual C++、C#、および Visual Basic は、いずれもジェネリックの定義と使用を完全にサポートしています。詳細については、「Visual Basic におけるジェネリック型」、「ジェネリックの概要 (C# プログラミング ガイド)」、および「Overview of Generics in C++」を参照してください。
入れ子にされた型とジェネリック
ジェネリック型の中で入れ子になった型は、外側のジェネリック型の型パラメータに依存する場合があります。共通言語ランタイムは、入れ子になった型自体のジェネリック型パラメータが存在しなくても、入れ子になった型をジェネリックと見なします。入れ子になった型のインスタンスを作成するときには、外側のすべてのジェネリック型の型引数を指定する必要があります。
参照
処理手順
方法 : リフレクション出力を使用してジェネリック型を定義する
概念
参照
System.Collections.ObjectModel