次の方法で共有


ジェネリック型パラメーターの制約 (C++/CLI)

ジェネリック型またはジェネリック メソッドの宣言で、制約の型パラメーターを修飾できます。 制約は、型引数が満たされている必要があるときに使用される入力する必要があります。 たとえば、制約に型引数が特定のインターフェイスを実装するか、または特定のクラスから継承しなければならないことがあります。

制約は省略可能;です パラメーターに制約を指定しないと、Objectとそのパラメーターの制約と同じです。

where type-parameter: constraint list

パラメーター

  • type-parameter
    型パラメーターの 1 つが、抑制されます。

  • 制約リスト
    制約リストには、制約の固有のコンマ区切りのリストです。 リストには、型パラメーターが実装されるインターフェイスを含めることができます。

    リストには、クラスを含めることができます。 基本クラスの制約を満たす型引数に制約と同じクラスである制約から派生しなければ。

    型引数は、パブリックなパラメーターなしのコンストラクターを持つ必要があることを示すために gcnew() ;を指定できます。または型引数を示す ref class は、クラス、インターフェイス、デリゲート、または配列型を含む参照型である必要があります。; または型引数を示す value class は値型である必要があります。 NullableT<> 以外の任意の値型を指定できます。

    、制約としてジェネリック パラメーターを指定できます。 、抑制する型によって提供される型引数が制約の型からの派生しなければ。 これは生の型制約と呼ばれます。

解説

制約句は型パラメーター、コロン (###:)、型パラメーターの制約の特性を指定する制約によって where 進んでから構成されます。 where は状況依存の;キーワードです。詳細については、" 状況依存のキーワード (C++ コンポーネント拡張) を参照してください。 空白を含む where の別の複数の句。

制約は、ジェネリック型またはジェネリック メソッドの引数として使用できる型の制約を型パラメーターに適用されます。

クラスの制約とインターフェイスの制約は引数の型が、指定されたクラスからも継承するか、指定したインターフェイスを実装しなければことを指定します。

ジェネリック型またはメソッドに対する制約のアプリケーションは、型またはメソッドのコードが制約された型の既知の機能を利用できるようになります。 たとえば、型パラメーターが IComparable<T> インターフェイスを実装すると、そのうちジェネリック クラスとして宣言する:

// 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 または doubleなどの組み込みの型には値型にすることはできません。 値型が派生クラスを持つことができないため、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 {};

参照

その他の技術情報

ジェネリック (C++ コンポーネント拡張)