ジェネリックの利点と制限事項
更新 : 2007 年 11 月
ジェネリック機能では、ジェネリック クラスまたはジェネリック メソッドによって操作される型を指定することにより、タイプ セーフに伴うユーザーの負担がコンパイラに転換されます。ジェネリック機能はコンパイル時に強制的に実行されるため、データ型が正しいかどうかをテストするコードを記述する必要はありません。また、型をキャストする必要性や、ランタイム エラーが発生する可能性も低くなります。
ジェネリックによって、複数の実装を使用することによるオーバーヘッドのないタイプ セーフが提供されます。たとえば、次の変数によって文字列のリンク リストを作成できます。
Dim llist As New LinkedList(Of String)
LinkedList<string> llist = new LinkedList<string>();
LinkedList<String^>^ llist = gcnew LinkedList<String^>();
基本型から継承してメンバをオーバーライドする必要はありません。リンク リストは、すぐに使用できるようになっています。.NET Framework で用意されているジェネリック コレクション型については、System.Collections.Generic および System.Collections.ObjectModel のトピックを参照してください。
ジェネリック コレクション型の利点は、タイプ セーフだけではありません。ジェネリック コレクションでは、値型をボックス化する必要がないため、一般に、値型の格納と操作のパフォーマンスが向上します。
汎用デリゲートを使用すると、複数のデリゲート クラスを作成せずに、タイプ セーフなコールバックを有効にできます。たとえば、Predicate<T> 汎用デリゲートでは、特定の型に対する独自の検索条件を実装するメソッドを作成したり、任意のメソッドを Array 型のメソッド (Find<T>、FindLast<T>、および FindAll<T> など) と共に使用できます。
また、動的に生成されるコードの中で、デリゲート型を生成せずに汎用デリゲートを使用することもできます。その結果、より多くのシナリオで、アセンブリ全体を生成せずに軽量の動的メソッドを使用できるようになります。詳細については、「方法 : 動的メソッドを定義および実行する」および「DynamicMethod」を参照してください。
多くの場合、Visual Basic、Visual C++、および C# のコンパイラは、ジェネリック メソッド呼び出しで使用される型をコンテキストから決定できるため、ジェネリック メソッドを使用するための構文が大幅に簡略化されます。たとえば、次のコードは、文字列の配列を検索する BinarySearch ジェネリック メソッドを呼び出すための短形式と長形式を示しています。短形式では、コンパイラはメソッド引数の型から正しい型パラメータを推測します。
Dim index As Integer = Array.BinarySearch(myArray, "test string")
Dim index As Integer = _
Array.BinarySearch(Of String)(myArray, "test string")
int index = Array.BinarySearch(myArray, "test string");
int index = Array.BinarySearch<string>(myArray, "test string");
int index = Array::BinarySearch(myArray, "test string");
int index = Array::BinarySearch<String^>(myArray, "test string");
ジェネリックの制限
.NET Framework version 2.0 のジェネリックには、次のような制限事項があります。
ジェネリック型は、MarshalByRefObject などのほとんどの基本クラスから派生できます (そして、制約を使用して、ジェネリック型のパラメータを MarshalByRefObject などの基本クラスから派生させるように要求することができます)。ただし、.NET Framework のこのリリースでは、コンテキスト バインドのジェネリック型はサポートされません。ContextBoundObject からジェネリック型を派生することは可能ですが、その型のインスタンスを作成しようとすると TypeLoadException が発生します。
列挙型はジェネリック型パラメータを持つことはできません。列挙型がジェネリックになるのは、(たとえば Visual Basic、C#、または C++ を使って定義されたジェネリック型の中に入れ子になっている場合など) 付随的な場合だけです。詳細については、「共通型システムの列挙型」を参照してください。
軽量の動的メソッドをジェネリックにすることはできません。動的メソッドの詳細については、「リフレクション出力による動的メソッドのシナリオ」を参照してください。
Visual Basic、C#、および C++ では、ジェネリック型に含まれる入れ子になった型がすべての外側の型の型パラメータに代入されない限り、入れ子になった型をインスタンス化することはできません。言い換えると、リフレクションでこれらの言語を使って定義された入れ子になった型は、すべての外側の型の型パラメータを含んでいます。これによって、外側の型の型パラメータが入れ子にされた型のメンバ定義で使用できるようになります。詳細については、MakeGenericType の「入れ子にされた型」を参照してください。
メモ : 動的アセンブリでコードを生成することによって、または MSIL アセンブラ (Ilasm.exe) を使用することによって定義された入れ子になった型には、外側の型の型パラメータを含める必要はありません。ただし、含めない場合、型パラメータは入れ子になったクラスのスコープに含まれなくなります。
詳細については、MakeGenericType の「入れ子にされた型」を参照してください。
参照
概念
参照
System.Collections.ObjectModel