ジェネリック インターフェイス (C++/CLI)Generic Interfaces (C++/CLI)

クラスの型パラメーターに適用される制約は、インターフェイスの型パラメーターに適用されるものと同じです (「ジェネリック クラス (C++/CLI)」を参照してください)。The restrictions that apply to type parameters on classes are the same as those that apply to type parameters on interfaces (see Generic Classes (C++/CLI)).

メソッドのオーバーロードを制御するルールは、ジェネリック クラスまたはジェネリック インターフェイス内の関数のルールと同じです。The rules that control function overloading are the same for functions within generic classes or generic interfaces.

明示的なインターフェイス メンバーの実装は、単純なインターフェイス型と同じ方法で構築されたインターフェイス型で機能します (次の例を参照してください)。Explicit interface member implementations work with constructed interface types in the same way as with simple interface types (see the following examples).

マネージド インターフェイスの詳細については、「interface class」を参照してください。For more information on interfaces, see interface class.

構文Syntax

[attributes] generic <class-key type-parameter-identifier[, ...]>
[type-parameter-constraints-clauses][accesibility-modifiers] interface class identifier [: base-list] {   interface-body} [declarators] ;

解説Remarks

attributesattributes
(省略可能) 追加の宣言情報。(Optional) Additional declarative information. 属性と属性クラスについては、「属性」を参照してください。For more information on attributes and attribute classes, see Attributes.

class-keyclass-key
class または typenameclass or typename

type-parameter-identifier(s)type-parameter-identifier(s)
コンマ区切りの識別子の一覧。Comma-separated identifiers list.

type-parameter-constraints-clausestype-parameter-constraints-clauses
ジェネリック型パラメーターの制約 (C++/CLI)」に指定された書式を使用します。Takes the form specified in Constraints on Generic Type Parameters (C++/CLI)

accessibility-modifiersaccessibility-modifiers
(省略可能) アクセシビリティ修飾子 (例: public、private)。(Optional) Accessibility modifiers (e.g. public, private).

identifieridentifier
インターフェイスの名前。The interface name.

base-listbase-list
(省略可能) 1 つまたは複数のコンマで区切られた明示的な基底インターフェイスを含む一覧。(Optional) A list that contains one or more explicit base interfaces separated by commas.

interface-bodyinterface-body
インターフェイス メンバーの宣言。Declarations of the interface members.

declaratorsdeclarators
(省略可能) この型に基づく変数の宣言。(Optional) Declarations of variables based on this type.

Example

次の例では、ジェネリック インターフェイスを宣言し、インスタンス化する方法を示します。The following example demonstrates how to declare and instantiate a generic interface. この例では、ジェネリック インターフェイス IList<ItemType> が宣言されます。In the example, the generic interface IList<ItemType> is declared. その後、2 つのジェネリック クラス (List1<ItemType>List2<ItemType>) によって、異なる実装で実装されます。It is then implemented by two generic classes, List1<ItemType> and List2<ItemType>, with different implementations.

// generic_interface.cpp
// compile with: /clr
using namespace System;

// An exception to be thrown by the List when
// attempting to access elements beyond the
// end of the list.
ref class ElementNotFoundException : Exception {};

// A generic List interface
generic <typename ItemType>
public interface class IList {
   ItemType MoveFirst();
   bool Add(ItemType item);
   bool AtEnd();
   ItemType Current();
   void MoveNext();
};

// A linked list implementation of IList
generic <typename ItemType>
public ref class List1 : public IList<ItemType> {
   ref class Node {
      ItemType m_item;

   public:
      ItemType get_Item() { return m_item; };
      void set_Item(ItemType value) { m_item = value; };

      Node^ next;

      Node(ItemType item) {
         m_item = item;
         next = nullptr;
      }
   };

   Node^ first;
   Node^ last;
   Node^ current;

   public:
   List1() {
      first = nullptr;
      last = first;
      current = first;
   }

   virtual ItemType MoveFirst() {
      current = first;
      if (first != nullptr)
        return first->get_Item();
      else
         return ItemType();
   }

   virtual bool Add(ItemType item) {
      if (last != nullptr) {
         last->next = gcnew Node(item);
         last = last->next;
      }
      else {
         first = gcnew Node(item);
         last = first;
         current = first;
      }
      return true;
   }

   virtual bool AtEnd() {
      if (current == nullptr )
        return true;
      else
        return false;
   }

   virtual ItemType Current() {
       if (current != nullptr)
         return current->get_Item();
       else
         throw gcnew ElementNotFoundException();
   }

   virtual void MoveNext() {
      if (current != nullptr)
       current = current->next;
      else
        throw gcnew ElementNotFoundException();
   }
};

// An array implementation of IList
generic <typename ItemType>
ref class List2 : public IList<ItemType> {
   array<ItemType>^ item_array;
   int count;
   int current;

   public:

   List2() {
      // not yet possible to declare an
      // array of a generic type parameter
      item_array = gcnew array<ItemType>(256);
      count = current = 0;
   }

   virtual ItemType MoveFirst() {
      current = 0;
      return item_array[0];
   }

   virtual bool Add(ItemType item) {
      if (count < 256)
         item_array[count++] = item;
      else
        return false;
      return true;
   }

   virtual bool AtEnd() {
      if (current >= count)
        return true;
      else
        return false;
   }

   virtual ItemType Current() {
      if (current < count)
        return item_array[current];
      else
        throw gcnew ElementNotFoundException();
   }

   virtual void MoveNext() {
      if (current < count)
         ++current;
      else
         throw gcnew ElementNotFoundException();
   }
};

// Add elements to the list and display them.
generic <typename ItemType>
void AddStringsAndDisplay(IList<ItemType>^ list, ItemType item1, ItemType item2) {
   list->Add(item1);
   list->Add(item2);
   for (list->MoveFirst(); ! list->AtEnd(); list->MoveNext())
   Console::WriteLine(list->Current());
}

int main() {
   // Instantiate both types of list.

   List1<String^>^ list1 = gcnew List1<String^>();
   List2<String^>^ list2 = gcnew List2<String^>();

   // Use the linked list implementation of IList.
   AddStringsAndDisplay<String^>(list1, "Linked List", "List1");

   // Use the array implementation of the IList.
   AddStringsAndDisplay<String^>(list2, "Array List", "List2");
}
Linked List
List1
Array List
List2

Example

この例では、ジェネリック インターフェイス IMyGenIface と、IMySpecializedInt を特殊化する 2 つの非ジェネリック インターフェイス (ImySpecializedStringIMyGenIface) を宣言します。This example declares a generic interface, IMyGenIface, and two non-generic interfaces, IMySpecializedInt and ImySpecializedString, that specialize IMyGenIface. 次に、2 つの特殊化されたインターフェイスが、2 つのクラス (MyIntClassMyStringClass) で実装されます。The two specialized interfaces are then implemented by two classes, MyIntClass and MyStringClass. この例では、ジェネリック インターフェイスを特殊化し、ジェネリック インターフェイスと非ジェネリック インターフェイスをインスタンス化し、インターフェイスの明示的に実装されたメンバーを呼び出します。The example shows how to specialize generic interfaces, instantiate generic and non-generic interfaces, and call the explicitly implemented members on the interfaces.

// generic_interface2.cpp
// compile with: /clr
// Specializing and implementing generic interfaces.
using namespace System;

generic <class ItemType>
public interface class IMyGenIface {
   void Initialize(ItemType f);
};

public interface class IMySpecializedInt: public IMyGenIface<int> {
   void Display();
};

public interface class IMySpecializedString: public IMyGenIface<String^> {
   void Display();
};

public ref class MyIntClass: public IMySpecializedInt {
   int myField;

public:
   virtual void Initialize(int f) {
      myField = f;
   }

   virtual void Display() {
      Console::WriteLine("The integer field contains: {0}", myField);
   }
};

public ref struct MyStringClass: IMySpecializedString {
   String^ myField;

public:
   virtual void Initialize(String^ f) {
      myField = f;
    }

   virtual void Display() {
      Console::WriteLine("The String field contains: {0}", myField);
   }
};

int main() {
   // Instantiate the generic interface.
   IMyGenIface<int>^ myIntObj = gcnew MyIntClass();

   // Instantiate the specialized interface "IMySpecializedInt."
   IMySpecializedInt^ mySpIntObj = (IMySpecializedInt^) myIntObj;

   // Instantiate the generic interface.
   IMyGenIface<String^>^ myStringObj = gcnew MyStringClass();

   // Instantiate the specialized interface "IMySpecializedString."
   IMySpecializedString^ mySpStringObj =
            (IMySpecializedString^) myStringObj;

   // Call the explicitly implemented interface members.
   myIntObj->Initialize(1234);
   mySpIntObj->Display();

   myStringObj->Initialize("My string");
   mySpStringObj->Display();
}
The integer field contains: 1234
The String field contains: My string

参照See also

ジェネリックGenerics