.NET のジェネリックGenerics in .NET

ジェネリックを使用すると、操作対象のデータ型に厳密に合わせてメソッド、クラス、構造体、またはインターフェイスを調整できます。Generics let you tailor a method, class, structure, or interface to the precise data type it acts upon. たとえば、任意の型のキーと値が許可される Hashtable クラスを使用する代わりに、Dictionary<TKey,TValue> ジェネリック クラスを使用して、キーと値に使用できる型を指定できます。For example, instead of using the Hashtable class, which allows keys and values to be of any type, you can use the Dictionary<TKey,TValue> generic class and specify the types allowed for the key and the value. ジェネリックの利点として、コードの再利用性やタイプ セーフの向上などを挙げることができます。Among the benefits of generics are increased code reusability and type safety.

ジェネリックの定義と使用Defining and Using Generics

ジェネリックは、格納または使用される 1 つ以上の型のプレースホルダー (型パラメーター) を持つクラス、構造体、インターフェイス、およびメソッドです。Generics are classes, structures, interfaces, and methods that have placeholders (type parameters) for one or more of the types that they store or use. ジェネリック コレクション クラスでは、格納するオブジェクトの型のプレースホルダーとして、型パラメーターを使用することがあります。型パラメーターは、そのフィールドの型やそのメソッドのパラメーター型として出現します。A generic collection class might use a type parameter as a placeholder for the type of objects that it stores; the type parameters appear as the types of its fields and the parameter types of its methods. ジェネリック メソッドでは、その戻り値の型として、またはいずれかの仮パラメーターの型として、型パラメーターを使用します。A generic method might use its type parameter as the type of its return value or as the type of one of its formal parameters. 単純なジェネリック クラスの定義を次のコードに示します。The following code illustrates a simple generic class definition.

generic<typename T>
public ref class Generics
{
public:
    T Field;
};
public class Generic<T>
{
    public T Field;
}
Public Class Generic(Of T)
    Public Field As T

End Class

ジェネリック クラスのインスタンスを作成する場合は、型パラメーターを置き換える実際の型を指定します。When you create an instance of a generic class, you specify the actual types to substitute for the type parameters. これで、構築されたジェネリック クラスと呼ばれる新しいジェネリック クラスが確立され、この中では、型パラメーターが、出現するすべての場所で、選択した型に置き換えられています。This establishes a new generic class, referred to as a constructed generic class, with your chosen types substituted everywhere that the type parameters appear. 次のコードに示すように、結果は選択した型に合わせたタイプ セーフなクラスになります。The result is a type-safe class that is tailored to your choice of types, as the following code illustrates.

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);
}
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);
}
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

ジェネリックの用語Generics terminology

.NET におけるジェネリックの説明では、次の用語が使用されます。The following terms are used to discuss generics in .NET:

  • ジェネリック型定義 は、テンプレートとして機能するクラス、構造体、またはインターフェイスの宣言で、格納または使用できる型のプレースホルダーを含みます。A generic type definition is a class, structure, or interface declaration that functions as a template, with placeholders for the types that it can contain or use. たとえば、 System.Collections.Generic.Dictionary<TKey,TValue> クラスには、キーと値の 2 つの型を含めることができます。For example, the System.Collections.Generic.Dictionary<TKey,TValue> class can contain two types: keys and values. ジェネリック型定義は単なるテンプレートであるため、ジェネリック型定義のクラス、構造体、またはインターフェイスのインスタンスを作成することはできません。Because a generic type definition is only a template, you cannot create instances of a class, structure, or interface that is a generic type definition.

  • ジェネリック型パラメーター(または 型パラメーター) は、ジェネリック型定義またはジェネリック メソッド定義のプレースホルダーです。Generic type parameters, or type parameters, are the placeholders in a generic type or method definition. System.Collections.Generic.Dictionary<TKey,TValue> ジェネリック型には、そのキーと値の型を表す 2 つの型パラメーター TKeyTValueがあります。The System.Collections.Generic.Dictionary<TKey,TValue> generic type has two type parameters, TKey and TValue, that represent the types of its keys and values.

  • 構築ジェネリック型(または 構築型) は、ジェネリック型定義のジェネリック型パラメーターに型を指定することによって得られる結果です。A constructed generic type, or constructed type, is the result of specifying types for the generic type parameters of a generic type definition.

  • ジェネリック型引数 は、ジェネリック型パラメーターを置き換える任意の型です。A generic type argument is any type that is substituted for a generic type parameter.

  • 一般的な用語である ジェネリック型 には、構築型とジェネリック型定義の両方が含まれます。The general term generic type includes both constructed types and generic type definitions.

  • ジェネリック型パラメーターの 共変性反変性 を使用すると、型引数がターゲットの構築型よりも強い派生型 (共変性) または弱い派生型 (反変性) である構築ジェネリック型を使用できます。Covariance and contravariance of generic type parameters enable you to use constructed generic types whose type arguments are more derived (covariance) or less derived (contravariance) than a target constructed type. 共変性と反変性は、 "変性" と総称されます。Covariance and contravariance are collectively referred to as variance. 詳細については、「共変性と反変性」を参照してください。For more information, see Covariance and Contravariance.

  • 制約 は、ジェネリック型パラメーターに適用される制限です。Constraints are limits placed on generic type parameters. たとえば、型パラメーターを、 System.Collections.Generic.IComparer<T> ジェネリック インターフェイスを実装する型に制限して、型のインスタンスを並べ替えることができるようにできます。For example, you might limit a type parameter to types that implement the System.Collections.Generic.IComparer<T> generic interface, to ensure that instances of the type can be ordered. また、型パラメーターを、特定の基底クラスを持つ型、パラメーターなしのコンストラクターを持つ型、または参照型や値型に制約することもできます。You can also constrain type parameters to types that have a particular base class, that have a parameterless constructor, or that are reference types or value types. ジェネリック型のユーザーは、制約を満たさない型引数に置き換えることはできません。Users of the generic type cannot substitute type arguments that do not satisfy the constraints.

  • ジェネリック メソッド定義 は、ジェネリック型パラメーターのリストと仮パラメーターのリストの 2 つのパラメーター リストを持つメソッドです。A generic method definition is a method with two parameter lists: a list of generic type parameters and a list of formal parameters. 次のコードに示すように、型パラメーターは、戻り値の型または仮パラメーターの型として指定できます。Type parameters can appear as the return type or as the types of the formal parameters, as the following code shows.

generic<typename T>
T Generic(T arg)
{
    T temp = arg;
    //...
    return temp;
}
T Generic<T>(T arg)
{
    T temp = arg;
    //...
    return temp;
}
Function Generic(Of T)(ByVal arg As T) As T
    Dim temp As T = arg
    '...
    Return temp
End Function

ジェネリック メソッドはジェネリック型または非ジェネリック型で指定できます。Generic methods can appear on generic or nongeneric types. メソッドがジェネリック型に属している、またはメソッドに仮パラメーターがあり、その型が外側の型のジェネリック パラメーターであるという理由だけでは、そのメソッドがジェネリックであるとは言えないことに注意してください。It is important to note that a method is not generic just because it belongs to a generic type, or even because it has formal parameters whose types are the generic parameters of the enclosing type. メソッドは、独自の型パラメーター リストを持つ場合にのみジェネリックとなります。A method is generic only if it has its own list of type parameters. 次のコードでは、 G メソッドのみがジェネリックです。In the following code, only method G is generic.

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;
    }
};
class A
{
    T G<T>(T arg)
    {
        T temp = arg;
        //...
        return temp;
    }
}
class Generic<T>
{
    T M(T arg)
    {
        T temp = arg;
        //...
        return temp;
    }
}
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

ジェネリックの利点と欠点Advantages and disadvantages of generics

ジェネリック コレクションやジェネリック デリゲートを使用することには多くの利点があります。There are many advantages to using generic collections and delegates:

  • インライン関数はタイプ セーフです。Type safety. ジェネリックによって、タイプ セーフの負担がユーザーからコンパイラに移ります。Generics shift the burden of type safety from you to the compiler. コンパイル時に正しいデータ型が適用されるため、これをテストするためのコードを記述する必要はありません。There is no need to write code to test for the correct data type because it is enforced at compile time. 型キャストの必要性や、ランタイム エラーが発生する可能性が減少します。The need for type casting and the possibility of run-time errors are reduced.

  • コードは少なければ少ないほど再利用が容易になります。Less code and code is more easily reused. 基本型から継承してメンバーをオーバーライドする必要はありません。There is no need to inherit from a base type and override members. たとえば、 LinkedList<T> はすぐに使える状態になっています。For example, the LinkedList<T> is ready for immediate use. たとえば、次の変数宣言で文字列のリンク リストを作成できます。For example, you can create a linked list of strings with the following variable declaration:

    LinkedList<String^>^ llist = gcnew LinkedList<String^>();
    
    LinkedList<string> llist = new LinkedList<string>();
    
    Dim llist As New LinkedList(Of String)()
    
  • パフォーマンスが向上します。Better performance. 通常、ジェネリック コレクション型では、値型をボックス化する必要がないため、値型の格納と操作のパフォーマンスが向上します。Generic collection types generally perform better for storing and manipulating value types because there is no need to box the value types.

  • 汎用デリゲートによって、複数のデリゲート クラスを作成せずにタイプ セーフなコールバックを使用できます。Generic delegates enable type-safe callbacks without the need to create multiple delegate classes. たとえば、 Predicate<T> 汎用デリゲートを使用すると、特定の型を対象とした独自の検索条件を実装するメソッドを作成し、 ArrayFindFindLastなどの FindAll型のメソッドと共に自分のメソッドを使用することができます。For example, the Predicate<T> generic delegate allows you to create a method that implements your own search criteria for a particular type and to use your method with methods of the Array type such as Find, FindLast, and FindAll.

  • ジェネリックによって、動的に生成されるコードが簡略化されます。Generics streamline dynamically generated code. 動的に生成されるコードでジェネリックを使用する場合、型を生成する必要がありません。When you use generics with dynamically generated code you do not need to generate the type. これにより、アセンブリ全体を生成する代わりに軽量の動的メソッドを使用できるシナリオの数が増えます。This increases the number of scenarios in which you can use lightweight dynamic methods instead of generating entire assemblies. 詳細については、方法:動的メソッドを定義および実行する」と DynamicMethod をご覧ください。For more information, see How to: Define and Execute Dynamic Methods and DynamicMethod.

ジェネリックの制限事項を次に示します。The following are some limitations of generics:

  • ジェネリック型は、 MarshalByRefObject などのほとんどの基本クラスから派生できます (制約を使用して、ジェネリック型パラメーターが MarshalByRefObjectのような基本クラスから派生することを要求できます)。Generic types can be derived from most base classes, such as MarshalByRefObject (and constraints can be used to require that generic type parameters derive from base classes like MarshalByRefObject). ただし、.NET では、コンテキスト バインドのジェネリック型はサポートしていません。However, .NET does not support context-bound generic types. ジェネリック型は、 ContextBoundObjectから派生できますが、その型のインスタンスを作成しようとすると、 TypeLoadExceptionが発生します。A generic type can be derived from ContextBoundObject, but trying to create an instance of that type causes a TypeLoadException.

  • 列挙型にジェネリック型パラメーターを含めることはできません。Enumerations cannot have generic type parameters. 列挙型が、単なる偶然によってジェネリックのみになる可能性はあります (たとえば、Visual Basic、C#、または C++ を使用して定義されたジェネリック型に入れ子にされているため)。An enumeration can be generic only incidentally (for example, because it is nested in a generic type that is defined using Visual Basic, C#, or C++). 詳細については、「 共通型システム」の「列挙型」を参照してください。For more information, see "Enumerations" in Common Type System.

  • 軽量の動的メソッドをジェネリックにすることはできません。Lightweight dynamic methods cannot be generic.

  • Visual Basic、C#、および C++ で、ジェネリック型に囲まれている入れ子にされた型は、外側のすべての型の型パラメーターに型が割り当てられていない限り、インスタンス化できません。In Visual Basic, C#, and C++, a nested type that is enclosed in a generic type cannot be instantiated unless types have been assigned to the type parameters of all enclosing types. 言い換えると、リフレクションでは、これらの言語を使用して定義されている入れ子にされた型には、その外側のすべての型の型パラメーターが含まれます。Another way of saying this is that in reflection, a nested type that is defined using these languages includes the type parameters of all its enclosing types. これによって、外側の型の型パラメーターを、入れ子にされた型のメンバー定義で使用できます。This allows the type parameters of enclosing types to be used in the member definitions of a nested type. 詳細については、「 MakeGenericType」の「入れ子にされた型」を参照してください。For more information, see "Nested Types" in MakeGenericType.

    注意

    動的アセンブリでコードを出力するか Ilasm.exe (IL アセンブラー) を使用して定義されている入れ子にされた型に、外側の型の型パラメーターを含める必要はありません。ただし、これらを含んでいない場合、型パラメーターは入れ子にされたクラスのスコープから外れます。A nested type that is defined by emitting code in a dynamic assembly or by using the Ilasm.exe (IL Assembler) is not required to include the type parameters of its enclosing types; however, if it does not include them, the type parameters are not in scope in the nested class.

    詳細については、「 MakeGenericType」の「入れ子にされた型」を参照してください。For more information, see "Nested Types" in MakeGenericType.

クラス ライブラリと言語サポートClass Library and Language Support

.NET では、次の名前空間に多数のジェネリック コレクション クラスが用意されています。.NET provides a number of generic collection classes in the following namespaces:

並べ替えと等価比較を実装するためのジェネリック インターフェイスは、イベント ハンドラー、変換、および検索述語の汎用デリゲート型と共に、 System 名前空間に用意されています。Generic interfaces for implementing sort and equality comparisons are provided in the System namespace, along with generic delegate types for event handlers, conversions, and search predicates.

ジェネリックのサポートは、ジェネリック型とジェネリック メソッドを調べるために System.Reflection 名前空間に追加され、ジェネリック型とジェネリック メソッドを含む動的アセンブリを出力するために System.Reflection.Emit に追加され、さらにジェネリックを含むソース グラフを生成するために System.CodeDom に追加されています。Support for generics has been added to the System.Reflection namespace for examining generic types and generic methods, to System.Reflection.Emit for emitting dynamic assemblies that contain generic types and methods, and to System.CodeDom for generating source graphs that include generics.

共通言語ランタイムでは、Microsoft Intermediate Language (MSIL) のジェネリック型をサポートするために、新しいオペコードとプレフィックスを提供しています ( StelemLdelemUnbox_AnyConstrainedReadonlyなど)。The common language runtime provides new opcodes and prefixes to support generic types in Microsoft intermediate language (MSIL), including Stelem, Ldelem, Unbox_Any, Constrained, and Readonly.

Visual C++、C#、および Visual Basic のすべてで、ジェネリックの定義と使用が完全にサポートされています。Visual C++, C#, and Visual Basic all provide full support for defining and using generics. 言語サポートの詳細については、「Visual Basic におけるジェネリック型」、「ジェネリックの概要」、および「Overview of Generics in Visual C++」 (Visual C++ のジェネリックの概要) を参照してください。For more information about language support, see Generic Types in Visual Basic, Introduction to Generics, and Overview of Generics in Visual C++.

入れ子にされた型とジェネリックNested Types and Generics

ジェネリック型に入れ子にされている型は、外側のジェネリック型の型パラメーターに依存している可能性があります。A type that is nested in a generic type can depend on the type parameters of the enclosing generic type. 共通言語ランタイムでは、独自のジェネリック型パラメーターがない場合でも、入れ子にされた型をジェネリックと見なします。The common language runtime considers nested types to be generic, even if they do not have generic type parameters of their own. 入れ子にされた型のインスタンスを作成するときに、外側のすべてのジェネリック型の型引数を指定する必要があります。When you create an instance of a nested type, you must specify type arguments for all enclosing generic types.

TitleTitle 説明Description
.NET の汎用コレクションGeneric Collections in .NET .NET のジェネリック コレクション クラスとその他のジェネリック型について説明します。Describes generic collection classes and other generic types in .NET.
配列とリストの操作に使用する汎用デリゲートGeneric Delegates for Manipulating Arrays and Lists 配列またはコレクションの要素に対して実行される変換、検索述語、およびアクションの汎用デリゲートについて説明します。Describes generic delegates for conversions, search predicates, and actions to be taken on elements of an array or collection.
ジェネリック インターフェイスGeneric Interfaces ジェネリック型のファミリ間に共通する機能を提供するジェネリック インターフェイスについて説明します。Describes generic interfaces that provide common functionality across families of generic types.
共変性と反変性Covariance and Contravariance ジェネリック型パラメーターの共変性と反変性について説明します。Describes covariance and contravariance in generic type parameters.
一般的に使用されるコレクション型Commonly Used Collection Types ジェネリック型など、.NET のコレクション型の特性と使用シナリオの概要について説明します。Provides summary information about the characteristics and usage scenarios of the collection types in .NET, including generic types.
ジェネリック コレクションを使用する状況When to Use Generic Collections ジェネリック コレクション型を使用するケースを決定するための一般的な規則について説明します。Describes general rules for determining when to use generic collection types.
方法: リフレクション出力を使用してジェネリック型を定義するHow to: Define a Generic Type with Reflection Emit ジェネリック型とジェネリック メソッドを含む動的アセンブリの生成方法について説明します。Explains how to generate dynamic assemblies that include generic types and methods.
Generic Types in Visual BasicGeneric Types in Visual Basic ジェネリック型の使用方法や定義方法に関するトピックなど、Visual Basic ユーザー向けにジェネリック機能について説明します。Describes the generics feature for Visual Basic users, including how-to topics for using and defining generic types.
ジェネリックの概要Introduction to Generics C# ユーザー向けにジェネリック型の定義方法や使用方法の概要について説明します。Provides an overview of defining and using generic types for C# users.
Visual C++ のジェネリックの概要Overview of Generics in Visual C++ ジェネリックとテンプレートの違いなど、C++ ユーザー向けにジェネリック機能について説明します。Describes the generics feature for C++ users, including the differences between generics and templates.

関連項目Reference

System.Collections.Generic

System.Collections.ObjectModel

System.Reflection.Emit.OpCodes