Поделиться через


Ограничения, применяемые к параметрам универсальных типов (C++/CLI)

В объявлениях универсального типа или метода можно указывать параметр типа с ограничениями.Ограничение требование, типы, используемые в качестве аргументов типа должны отвечать.Например, ограничение может оказаться, что аргумент типа должен реализовать определенный интерфейс или быть производным от определенного класса.

Ограничения являются необязательными; не указывая ограничение для параметра эквивалентен ограничить этот параметр в Object.

where type-parameter: constraint list

Параметры

  • тип параметра
    Один из параметров типа быть ограниченным.

  • список ограничений
    список ограничений разделенный запятыми список спецификаций ограничения.Список может содержать интерфейсы, который реализует параметр типа.

    Список может также включать класс.Для аргумента типа для удовлетворения ограничение базового класса, он должен быть одним и тем же классом, как ограничение или производной от ограничения.

    Также можно указать gcnew() для указания того, что аргумент типа должен иметь открытый конструктор без параметров. или ref class, чтобы указать аргумент типа должен быть ссылочным типом, включая любой класс, интерфейс, делегат или тип массива; или value class, чтобы указать аргумент типа должен быть типом значения.Любой тип <Т> значения, отличные от Null.

    Также можно указать универсальный шаблон параметр как ограничение.Предоставленный аргумент типа для типа можно ограничить должен быть либо производный от типа ограничения.Это называется нагим ограничением типа.

Заметки

Предложение ограничения состоит из where определяется параметром типа, двоеточия (:) и ограничением, которое определяет природу ограничения для параметра типа.where контекст-чувствительное ключевое слово; см. Контекстные ключевые слова (расширения компонентов C++) дополнительные сведения.Несколько предложений where пробелами.

Ограничения применяются к параметрам типа для установки ограничения на типы, которые можно использовать в качестве аргументов для универсального типа или метода.

Ограничения класса и интерфейса определяют, что типы аргументов должны быть либо при наследовании из указанного класса или реализовав указанный интерфейс.

Приложение ограничений к типу ресурса или метод позволяет коду в тех типе или методе воспользоваться преимуществами стандартных функций ограниченных типов.Например, можно объявить универсальный шаблон класс те, что параметр типа, реализующего интерфейс IComparableТ :

// 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 или Двойное с плавающей запятой.Поскольку типы значений не могут иметь производные классы только один класс всегда сможет отвечать ограничение.В этом случае универсальный шаблон можно переписать с параметром типа замененный определенным типом значения.

Ограничения необходимы в некоторых случаях поскольку компилятор не допускает использование методов или других функций неизвестного типа, если ограничения не будут подразумевать, что неизвестный тип поддерживает методы или интерфейсы.

Несколько ограничений для одного параметра типа можно задать в списке с разделителями-запятыми

// 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 для каждого параметра типа.Примеры.

// 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++)