.NET Framework におけるジェネリック
ジェネリックを使用すると、操作対象のデータ型に厳密に合わせてメソッド、クラス、構造体、またはインターフェイスを調整できます。 たとえば、任意の型のキーと値を許可する Hashtable クラスを使用する代わりに、Dictionary<TKey, TValue> ジェネリック クラスを使用してキーと値に許可する型を指定できます。 ジェネリックの利点の 1 つは、コードの再利用性とタイプ セーフが向上することです。
ここでは、.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 Generics
{
public:
T Field;
};
ジェネリック クラスのインスタンスを作成するときには、型パラメーターと置き換える実際の型を指定します。 これにより、型パラメーターが出現するすべての場所を選択した型に置き換えた新しいジェネリック クラスが作成されます。これは、構築されたジェネリック クラスと呼ばれます。 次のコードに示すように、作成されたクラスは選択した型に適合したタイプ セーフなクラスです。
Public Shared Sub Main()
Dim g As New Generic(Of String)
g.Field = "A string"
'...
Console.WriteLine("Generic.Field = ""{0}""", g.Field)
Console.WriteLine("Generic.Field.GetType() = {0}", g.Field.GetType().FullName)
End Sub
public static void Main()
{
Generic<string> g = new Generic<string>();
g.Field = "A string";
//...
Console.WriteLine("Generic.Field = \"{0}\"", g.Field);
Console.WriteLine("Generic.Field.GetType() = {0}", g.Field.GetType().FullName);
}
static void Main()
{
Generics<String^>^ g = gcnew Generics<String^>();
g->Field = "A string";
//...
Console::WriteLine("Generics.Field = \"{0}\"", g->Field);
Console::WriteLine("Generics.Field.GetType() = {0}", g->Field->GetType()->FullName);
}
ページのトップへ
ジェネリックの用語
.NET Framework のジェネリックに関する用語を次に示します。
"ジェネリック型の定義" とは、クラス、構造体、インターフェイスで格納または使用できる型のプレースホルダーを使用する、テンプレートとして機能するクラス、構造体、インターフェイスの宣言です。 たとえば、System.Collections.Generic.Dictionary<TKey, TValue> クラスは、キーと値の 2 つの型を格納できます。 ジェネリック型定義は単なるテンプレートにすぎないため、ジェネリック型定義であるクラス、構造体、またはインターフェイスのインスタンスを作成することはできません。
"ジェネリック型パラメーター" (または "型パラメーター") とは、ジェネリック型の定義またはジェネリック メソッドの定義に含まれるプレースホルダーです。 System.Collections.Generic.Dictionary<TKey, TValue> ジェネリック型には、キーと値の型を表す TKey と TValue の 2 つの型パラメーターがあります。
"構築ジェネリック型" (または "構築された型") とは、ジェネリック型の定義のジェネリック型パラメーターに型を指定することによって作成されたジェネリック型です。
"ジェネリック型引数" とは、ジェネリック型パラメーターと置き換えられる任意の型です。
一般用語である "ジェネリック型" には、構築された型とジェネリック型の定義の両方が含まれます。
ジェネリック型パラメーターの "共変性" と "反変性" により、対象の構築された型よりも強い派生 (共変性) または弱い派生 (反変性) の型の引数を持つ構築ジェネリック型を使用できます。 共変性と反変性は、"分散" と総称されます。 詳細については、「ジェネリックの共変性と反変性」を参照してください。
"制約" とは、ジェネリック型パラメーターの制限です。 たとえば、型パラメーターを System.Collections.Generic.IComparer<T> ジェネリック インターフェイスを実装する型に制限することで、型のインスタンスを確実に順序付けることができます。 また、型パラメーターを特定の基本クラスを持つ型、既定のコンストラクターを持つ型、参照型または値型である型に制約することもできます。 ジェネリック型のユーザーは、制約を満たさない型引数を置き換えることはできません。
"ジェネリック メソッドの定義" とは、ジェネリック型パラメーターのリストと、仮パラメーターのリストの 2 つのパラメーター リストを持つメソッドです。 次のコードに示すように、型パラメーターは、戻り値の型または仮パラメーターの型として出現します。
Function Generic(Of T)(ByVal arg As T) As T
Dim temp As T = arg
'...
Return temp
End Function
T Generic<T>(T arg)
{
T temp = arg;
//...
return temp;
}
generic<typename T>
T Generic(T arg)
{
T temp = arg;
//...
return temp;
}
ジェネリック メソッドは、ジェネリック型または非ジェネリック型で出現できます。 メソッドはジェネリック型に属しているだけである、または、型が外側の型のジェネリック パラメーターである仮パラメーターを持っているだけであるという理由から、メソッドはジェネリックではないという点に注意することが重要です。 メソッドがジェネリックになるのは、そのメソッドが独自の型パラメーター リストを持つ場合だけです。 次のコードでは、G メソッドだけがジェネリックです。
Class A
Function G(Of T)(ByVal arg As T) As T
Dim temp As T = arg
'...
Return temp
End Function
End Class
Class Generic(Of T)
Function M(ByVal arg As T) As T
Dim temp As T = arg
'...
Return temp
End Function
End Class
class A
{
T G<T>(T arg)
{
T temp = arg;
//...
return temp;
}
}
class Generic<T>
{
T M(T arg)
{
T temp = arg;
//...
return temp;
}
}
ref class A
{
generic<typename T>
T G(T arg)
{
T temp = arg;
//...
return temp;
}
};
generic<typename T>
ref class Generic
{
T M(T arg)
{
T temp = arg;
//...
return temp;
}
};
ページのトップへ
クラス ライブラリと言語サポート
.NET Framework には、次の名前空間に多数のジェネリック コレクション クラスが用意されています。
System.Collections.Generic 名前空間には、List<T> ジェネリック クラスや Dictionary<TKey, TValue> ジェネリック クラスなど、.NET Framework に用意されているジェネリック コレクション型のほとんどが登録されています。
System.Collections.ObjectModel 名前空間には、ReadOnlyCollection<T> ジェネリック クラスなど、クラスのユーザーにオブジェクト モデルを公開するうえで役立つその他のジェネリック コレクション型が登録されています。
並べ替えと等式による比較を実装するためのジェネリック インターフェイスは、イベント ハンドラー、変換、および検索述語の汎用デリゲート型と共に、System 名前空間に提供されています。
ジェネリックのサポートは、System.Reflection 名前空間 (ジェネリック型とジェネリック メソッドのチェック用)、System.Reflection.Emit (ジェネリック型とジェネリック メソッドを含む動的アセンブリの出力用)、および System.CodeDom (ジェネリックを含むソース グラフの生成用) に追加されています。
共通言語ランタイムは、Stelem、Ldelem、Unbox_Any、Constrained、Readonly など、Microsoft Intermediate Language (MSIL) でジェネリック型をサポートするための新しいオペコードとプレフィックスを提供します。
Visual C++、C#、および Visual Basic は、いずれもジェネリックの定義と使用を完全にサポートしています。 言語サポートの詳細については、「Visual Basic におけるジェネリック型 (Visual Basic)」、「ジェネリックの概要 (C# プログラミング ガイド)」、および「Overview of Generics in Visual C++」を参照してください。
ページのトップへ
入れ子にされた型とジェネリック
ジェネリック型の中で入れ子になった型は、外側のジェネリック型の型パラメーターに依存する場合があります。 共通言語ランタイムは、入れ子になった型自体のジェネリック型パラメーターが存在しなくても、入れ子になった型をジェネリックと見なします。 入れ子になった型のインスタンスを作成するときには、外側のすべてのジェネリック型の型引数を指定する必要があります。
ページのトップへ
関連トピック
タイトル |
説明 |
---|---|
.NET Framework のジェネリック コレクション クラスおよびその他のジェネリック型について説明します。 |
|
変換、検索述語、配列またはコレクションの要素に対して実行するアクションのための汎用デリゲートについて説明します。 |
|
ジェネリック型のファミリ間で共通の機能を提供するジェネリック インターフェイスについて説明します。 |
|
ジェネリック型パラメーターの共変性と反変性について説明します。 |
|
ジェネリックを使用する利点と制限について要点を説明します。 |
|
ジェネリック型を含む .NET Framework のコレクション型の特性と使用シナリオの概要を説明します。 |
|
どのような場合にジェネリック コレクション型を使用するかを判断するための一般的な規則について説明します。 |
|
ジェネリック型とジェネリック メソッドを含む動的アセンブリを生成する方法について説明します。 |
|
Visual Basic ユーザー向けにジェネリック機能について説明し、ジェネリック型を使用および定義する方法を説明したトピックを紹介します。 |
|
C# ユーザー向けに、ジェネリック型の定義と使用について概説します。 |
|
C++ ユーザー向けに、ジェネリックとテンプレートの違いを含め、ジェネリック機能について説明します。 |
ページのトップへ
参照
System.Collections.ObjectModel
System.Reflection.Emit.OpCodes
ページのトップへ