C#

75.C# - 형식 매개변수에 대한 제약조건

Godffs 2009. 8. 18. 19:47
반응형

제네릭 클래스를 정의하는 경우 클래스를 인스턴스화할 때 클라이언트 코드에서 형식 인수에 사용할 수 있는 형식의 종류에 제약 조건을 적용할 수 있습니다. 클라이언트 코드가 제약 조건에서 허용하지 않는 형식을 사용하여 클래스를 인스턴스화하려고 하면 컴파일 타임 오류가 발생합니다. 이러한 제한을 제약 조건이라고 합니다. 제약 조건은 컨텍스트 키워드 where를 사용하여 지정합니다.


 

where T: struct -> 형식 인수는 값 형식. Nullable를 제외한 임의의 값 형식
                           지정가능

where T : class -> 형식 인수는 참조 형식
                         (모든 클래스, 인터페이스, 대리자 또는 배열 형식에도 적용)

where T : new() -> 형식 인수가 매개 변수 없는 공용 생성자여야 함.
                            다른 제약 조건과 함께 사용하는 경우
new()
                            제약 조건은 마지막에 지정

where T : <기본 클래스 이름> -> 형식 인수가 지정된 기본 클래스이거나
                                             지정된 기본 클래스에서 파생되어야 함

where T : <인터페이스 이름> -> 형식 인수가 지정된 인터페이스이거나 지정된
                            인터페이스로 구현. 여러 인터페이스 제약 조건 지정가능.
                                    제한하는 인터페이스는 제네릭이 될 수도 있습니다.

where T : U -> T에 대해 지정한 형식 인수가 U에 대해 지정한 인수이거나
                      인수에서 파생되어야 한다.( = naked 형식 제약 조건 )

제약조건 사용이유
제네릭 목록의 항목을 검사하여 그 유효성 여부를 확인하거나 이 항목을
다른 항목과 비교하려는 경우, 컴파일러는 클라이언트 코드에서 지정할 수 있는
모든 형식 인수에 대해 호출해야 할 메서드나 연산자가 지원되는지 확인해야
합니다. 하나 이상의 제약 조건을 제네릭 클래스 정의에 적용하면 이러한 확인이
가능합니다. 예를 들어, 기본 클래스 제약 조건에서는 이 형식의 개체와
이 형식에서 파생된 개체만이 형식 인수로 사용될 수 있음을 컴파일러에
알립니다. 컴파일러에서 이를 확인하면 사용자는 제네릭 클래스에서 해당 형식의
메서드를 호출할 수 있습니다. 제약 조건은 컨텍스트 키워드
where를 사용하여 적용됩니다.


Program.cs
using System;
public class CarValue<T> where T : struct //where T : class 하면
{                                                        string형 성공 // struct = 값 타입

}
public class CarReference<T> where T : class { } //class = 참조타입
public class CarNew<T> where T : new() { } //Default 생성자
public class CarClass<T> where T : Hyundai { }//Hyundai에서 파생
public class CarInterface<T> where T : IKs { } //IKs인터페이스

public interface IKs { } //인터페이스
public class Hyundai { } //부모클래스
public class Sonata : Hyundai, IKs { } //자식이 부모와 Iks를 상속

Program.cs
public class 형식매개변수에대한제약조건
{
    public static void Main()
    {
        CarValue<int> c = new CarValue<int>();// 값 타입 struct이면 성공    
        //Car<string> cs = new Car<string>(); //값 타입이 class이면 성공
        CarReference<string> cs = new CarReference<string>(); //class성공
        CarNew<int> cn = new CarNew<int>(); //new()성공

    CarClass<Sonata> cc = new CarClass<Sonata>(); //사용자 정의 타입
                                                                        현대클래스로부터 파생
    CarInterface<IKs> h = new CarInterface<IKs>(); // 인터페이스 타입
                                                                            클래스가 들어옴

    }
}
반응형