ジェネリック型パラメーターの制約 (C++/CLI)
ジェネリック型またはジェネリック メソッド宣言で、制約の型パラメーターを修飾できます。制約は、型引数が満たされている必要があるときに使用される入力する必要条件です。たとえば、制約に型引数が特定のインターフェイスを実装したり、特定のクラスから継承することである場合があります。
制約はオプションです。; パラメーターに制約を指定しないと、 Objectとそのパラメーターの制約と同じです。
where type-parameter: constraint list
パラメーター
型パラメーター
型パラメーターは 1、抑制されます。制約リスト
制約リストは 、制約の仕様 (コンマ区切りリストです。リストは型パラメーターが実装するインターフェイスを含めることができます。一覧には、クラスを含めることができます。基本クラス制約を満たす型の引数に制約と同じクラスである制約から派生します。
また、型引数は、パブリックのパラメーターなしのコンストラクターを持つ必要があることを示すために gcnew() を指定できます。; または型引数を示す ref class は、クラス、インターフェイス、デリゲート、または配列型を含む参照型である必要があります; または型引数を示す value class は値型である必要があります。null 許容 <T> を除く)は値型でも指定できます。
また、制約としてジェネリック パラメーターを指定できます。抑制する型に渡される型引数が制約の型であるから派生します。これは修飾されていない型の制約と呼びます。
解説
制約句は型パラメーター、コロン (:)、および型パラメーターの制限の性質を指定する制約によって where " から構成されます。where は状況依存のキーワードです。; 詳細については 状況依存のキーワード (C++ コンポーネント拡張) 、 " " を参照してください。領域を持つ where の別の複数の句。
型パラメーターに制約がジェネリック型またはメソッドに引数として使用できる型に制限があるときに適用されます。
クラスとインターフェイスの制約は引数の型が指定されたクラスからの継承するか、指定されたインターフェイスを実装することを指定します。
ジェネリック型またはメソッドに対する制約のアプリケーションは、その型またはメソッドのコードが制約された型の既知の機能を利用できるようにします。たとえば、型パラメーターが IComparableT インターフェイスを実装すると、ジェネリック クラスを、こうしたで宣言できます:
// generics_constraints_1.cpp
// compile with: /c /clr
using namespace System;
generic <typename T>
where T : IComparable<T>
ref class List {};
この制約はT に使用する型引数がコンパイル時に IComparable<T> を実行する必要があります。また、インターフェイス メソッドが、 CompareToなど、呼び出されるようにします。キャストは型パラメーターのインスタンスに必要インターフェイス メソッドをダイヤルする必要はありません。
型引数クラスの静的メソッドは、型パラメーターで呼び出すことはできません; これらは実際の名前付きの型を介してのみ呼び出すことができます。
制約は int または 倍精度浮動小数点型などの組み込み型を含む、値型にすることはできません。値型は、派生クラスを持つことができないため、 1 は一つのクラスだけが制約を満たせた。その場合は、ジェネリックは特定の値型に置換される型パラメーターと書き直すことができます。
制約は不明な型でメソッドまたはインターフェイスをサポートするように制約が意味するコンパイラは、メソッドを使用または不明な型の他の機能を配置する場合によっては必須です。
同じ型パラメーターに複数の制約をコンマ区切りのリストで指定できます。
// generics_constraints_2.cpp
// compile with: /c /clr
using namespace System;
using namespace System::Collections::Generic;
generic <typename T>
where T : List<T>, IComparable<T>
ref class List {};
複数の型パラメーターによって、各型パラメーターに対して where の 1 種類の句を使用します。次に例を示します。
// generics_constraints_3.cpp
// compile with: /c /clr
using namespace System;
using namespace System::Collections::Generic;
generic <typename K, typename V>
where K: IComparable<K>
where V: IComparable<K>
ref class Dictionary {};
まとめると、制約を次の規則に従ってコードで使用する場合:
複数の制約がない場合は、制約は、任意の順序で表示されることがあります。
制約は、抽象基本クラスなどのクラス型でもかまいません。ただし、制約は、値型またはシール クラスに指定できません。
制約自体は型パラメーターにすることはできません。オープン構築型の型パラメーターを含めることができます。次に例を示します。
// generics_constraints_4.cpp // compile with: /c /clr generic <typename T> ref class G1 {}; generic <typename Type1, typename Type2> where Type1 : G1<Type2> // OK, G1 takes one type parameter ref class G2{};
使用例
次の例では、型パラメーターの呼び出しのインスタンス メソッドに、制約を使用します。
// generics_constraints_5.cpp
// compile with: /clr
using namespace System;
interface class IAge {
int Age();
};
ref class MyClass {
public:
generic <class ItemType> where ItemType : IAge
bool isSenior(ItemType item) {
// Because of the constraint,
// the Age method can be called on ItemType.
if (item->Age() >= 65)
return true;
else
return false;
}
};
ref class Senior : IAge {
public:
virtual int Age() {
return 70;
}
};
ref class Adult: IAge {
public:
virtual int Age() {
return 30;
}
};
int main() {
MyClass^ ageGuess = gcnew MyClass();
Adult^ parent = gcnew Adult();
Senior^ grandfather = gcnew Senior();
if (ageGuess->isSenior<Adult^>(parent))
Console::WriteLine("\"parent\" is a senior");
else
Console::WriteLine("\"parent\" is not a senior");
if (ageGuess->isSenior<Senior^>(grandfather))
Console::WriteLine("\"grandfather\" is a senior");
else
Console::WriteLine("\"grandfather\" is not a senior");
}
ジェネリック型パラメーターで制約として使用すると、修飾されていない型の制約と呼びます。修飾されていない型制約が独自の型パラメーターのメンバー関数に包含型の型パラメーターにそのパラメーターを制限する必要がある場合に便利です。
次の例では、 T は追加のメソッドのコンテキストで修飾されていない型制約です。
修飾されていない型の制約は、ジェネリック クラスの定義で使用できます。ジェネリック クラスで修飾されていない型の制約の有効性は、コンパイラが修飾されていない型の制約についての情報は一切仮定できるが、 Objectから派生するため制限されます。、 2 種類のパラメーター間の継承関係を実装するシナリオでジェネリック クラスの修飾されていない型制約を使用します。
// generics_constraints_6.cpp
// compile with: /clr /c
generic <class T>
ref struct List {
generic <class U>
where U : T
void Add(List<U> items) {}
};
generic <class A, class B, class C>
where A : C
ref struct SampleClass {};