Share via


제네릭 형식 매개 변수에 대한 제약 조건(C++/CLI)

제네릭 형식 또는 메서드 선언에서 제약 조건을 사용하여 형식 매개 변수 를 한정할 수 있습니다. 제약 조건은 형식 인수로 사용되는 형식이 충족해야 하는 요구 사항입니다. 예를 들어, 형식 인수가 특정 인터페이스를 구현하거나 특정 클래스에서 상속해야 제한할 수 있습니다.

제약 조건은 선택 사항입니다. 매개 변수에 제약 조건을 지정하지 않는 것은 제약 조건을 사용하는 Object 것과 같습니다.

구문

where type-parameter : constraint-list

매개 변수

type-parameter
제한할 형식 매개 변수 식별자 중 하나입니다.

constraint-list
제약 조건 사양의 쉼표로 구분된 목록입니다. 목록에는 .에서 구현할 인터페이스가 type-parameter포함될 수 있습니다.

이 목록은 클래스를 포함할 수도 있습니다. 기본 클래스 제약 조건을 충족하려면 형식 인수가 제약 조건과 동일한 클래스이거나 제약 조건에서 파생되어야 합니다. 형식 인수가 모든 class, interface또는 delegatearray 형식을 포함하는 참조 형식이어야 함을 나타내도록 지정 ref class 합니다. 형식 인수가 값 형식이어야 함을 나타내도록 지정 value class 합니다. Nullable<T>를 제외한 임의의 값 형식을 지정할 수 있습니다.

형식 인수에 공용 매개 변수가 없는 생성자가 있어야 함을 나타내도록 지정할 gcnew() 수도 있습니다.

제네릭 매개 변수를 제약 조건으로 지정할 수도 있습니다. 제약하는 형식에 대해 제공된 형식 인수는 제약 조건의 형식이거나 파생되어야 합니다. 이 매개 변수를 naked 형식 제약 조건이라고 합니다.

설명

제약 조건 절은 형식 매개 변수, 콜론(:) 및 형식 매개 변수에 대한 제한의 특성을 지정하는 제약 조건으로 구성 where 됩니다. where는 상황에 맞는 키워드입니다. 자세한 내용은 상황에 맞는 키워드(keyword) 참조하세요. 여러 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와 같은 인터페이스 메서드의 호출을 허용합니다. 인터페이스 메서드를 호출하기 위해 형식 매개 변수의 인스턴스를 캐스팅할 필요가 없습니다.

형식 인수 클래스의 정적 메서드는 형식 매개 변수를 통해 호출할 수 없습니다. 실제 명명된 형식을 통해서만 호출할 수 있습니다.

제약 조건은 값 형식(예: 또는 double.)과 같은 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 {};

다음 규칙에 따라 코드에서 제약 조건을 사용합니다.

  • 여러 제약 조건이 나열될 경우 순서에 상관없이 표시될 수 있습니다.

  • 제약 조건은 추상 기본 클래스와 같은 클래스 형식일 수도 있습니다. 그러나 제약 조건은 값 형식이나 sealed 클래스일 수 없습니다.

  • 제약 조건 자체는 형식 매개 변수일 수 없지만 형식 매개 변수는 열린 생성된 형식에 포함될 수 있습니다. 다음은 그 예입니다.

    // 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");
}
"parent" is not a senior
"grandfather" is a senior

제네릭 형식 매개 변수를 제약 조건으로 사용하는 경우 이를 naked 형식 제약 조건이라고 합니다. 고유한 형식 매개 변수가 있는 멤버 함수가 포함 형식의 형식 매개 변수에 해당 매개 변수를 제한할 필요가 있을 때 naked 형식 제약 조건이 유용합니다.

다음 예제에서 TAdd 메서드 컨텍스트의 naked 형식 제약 조건입니다.

naked 형식 제약 조건은 제네릭 클래스 정의에서 사용할 수도 있습니다. 컴파일러에서는 naked 형식 제약 조건이 Object에서 파생된다는 점을 제외하고는 이 제약 조건에 대해 어떠한 정보도 알 수 없으므로 제네릭 클래스가 있는 naked 형식 제약 조건의 유용성에는 한계가 있습니다. 두 형식 매개 변수 사이의 상속 관계를 적용하려는 시나리오에서 제네릭 클래스에 naked 형식 제약 조건을 사용합니다.

// 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 {};

참고 항목

제네릭