--- title: "Generic Interfaces (C++/CLI)" ms.date: "10/12/2018" ms.topic: "reference" helpviewer_keywords: ["generic interfaces", "interfaces, generic [C++}"] ms.assetid: f3da788a-ba83-4db7-9dcf-9b95a8fb9d1a --- # Generic Interfaces (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)](generic-classes-cpp-cli.md)). 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). For more information on interfaces, see [interface class](interface-class-cpp-component-extensions.md). ## Syntax ```cpp [attributes] generic [type-parameter-constraints-clauses][accesibility-modifiers] interface class identifier [: base-list] { interface-body} [declarators] ; ``` ## Remarks *attributes*
(Optional) Additional declarative information. For more information on attributes and attribute classes, see **Attributes**. *class-key*
**`class`** or **`typename`** *type-parameter-identifier(s)*
Comma-separated identifiers list. *type-parameter-constraints-clauses*
Takes the form specified in [Constraints on Generic Type Parameters (C++/CLI)](constraints-on-generic-type-parameters-cpp-cli.md) *accessibility-modifiers*
(Optional) Accessibility modifiers (e.g. **public, private**). *identifier*
The interface name. *base-list*
(Optional) A list that contains one or more explicit base interfaces separated by commas. *interface-body*
Declarations of the interface members. *declarators*
(Optional) Declarations of variables based on this type. ## Example The following example demonstrates how to declare and instantiate a generic interface. In the example, the generic interface `IList` is declared. It is then implemented by two generic classes, `List1` and `List2`, with different implementations. ```cpp // 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 public interface class IList { ItemType MoveFirst(); bool Add(ItemType item); bool AtEnd(); ItemType Current(); void MoveNext(); }; // A linked list implementation of IList generic public ref class List1 : public IList { 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 ref class List2 : public IList { array^ item_array; int count; int current; public: List2() { // not yet possible to declare an // array of a generic type parameter item_array = gcnew array(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 void AddStringsAndDisplay(IList^ 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^ list1 = gcnew List1(); List2^ list2 = gcnew List2(); // Use the linked list implementation of IList. AddStringsAndDisplay(list1, "Linked List", "List1"); // Use the array implementation of the IList. AddStringsAndDisplay(list2, "Array List", "List2"); } ``` ```Output Linked List List1 Array List List2 ``` ## Example This example declares a generic interface, `IMyGenIface`, and two non-generic interfaces, `IMySpecializedInt` and `ImySpecializedString`, that specialize `IMyGenIface`. 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. ```cpp // generic_interface2.cpp // compile with: /clr // Specializing and implementing generic interfaces. using namespace System; generic public interface class IMyGenIface { void Initialize(ItemType f); }; public interface class IMySpecializedInt: public IMyGenIface { void Display(); }; public interface class IMySpecializedString: public IMyGenIface { 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^ myIntObj = gcnew MyIntClass(); // Instantiate the specialized interface "IMySpecializedInt." IMySpecializedInt^ mySpIntObj = (IMySpecializedInt^) myIntObj; // Instantiate the generic interface. IMyGenIface^ 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(); } ``` ```Output The integer field contains: 1234 The String field contains: My string ``` ## See also [Generics](generics-cpp-component-extensions.md)