`new` 제약 조건

new 제약 조건 (new constraint, C# 참조)

제네릭 메서드나 제네릭 클래스를 만들 때, 타입 매개변수로 받은 T를 실제로 new로 생성해야 하는 상황이 있어요. 그런데 T가 어떤 모양이 될지 모르니까 컴파일러가 "아무 타입이나 받을 수는 없는데 어떻게 생성을 보장하지?" 난감해 하죠. 이때 쓰는 게 바로 new 제약 조건이에요.

출처: new constraint - C# Reference

본문

new 제약 조건은 제네릭 클래스나 메서드 선언에서 타입 인자가 반드시 public 매개변수 없는 생성자(parameterless constructor)를 가져야 한다는 조건이에요. 즉 "이 타입은 아무런 인자를 받지 않고 기본 생성자로 만들 수 있어야 해요"라고 미리 보장하는 거죠.

단, new 제약 조건을 쓰려면 타입이 abstract(추상)이면 안 돼요. 추상 클래스는 인스턴스로 만들 수 없으니, 생성이 가능하다는 조건과 어긋나기 때문이에요.

new 제약 조건은 제네릭 클래스가 타입의 새 인스턴스를 직접 만들어야 할 때 타입 매개변수에 붙여줘요. 아래 예시를 볼게요.

class ItemFactory<T> where T : new()
{
    public T GetNewItem()
    {
        return new T();
    }
}

여기서 where T : new()가 보이죠? 그래서 GetNewItem() 안에서 new T()로 인스턴스를 만들 수 있어요. T가 기본 생성자를 가진다는 게 조건으로 보장되어 있으니까요.

만약 new() 제약 조건을 다른 제약 조건과 함께 쓴다면, 반드시 맨 마지막에 지정해야 해요. 순서가 틀리면 컴파일 오류가 나요.

public class ItemFactory2<T>
    where T : IComparable, new()
{  }

위 코드에서는 IComparable을 먼저, 그다음에 new()를 마지막으로 지정했죠. 이렇게 해야 T가 비교 가능하면서도 기본 생성은 항상 보장된다는 의미가 돼요.

new 키워드는 이 제약 조건 외에도 두 가지 용도로 더 쓰여요. 하나는 타입의 인스턴스를 생성하는 연산자, 다른 하나는 멤버 선언 수정자로 쓰는 경우예요. 이 제약 조건과 구분해서 기억해 두면 좋아요.

타입 매개변수에 붙일 수 있는 다양한 제약 조건을 종합적으로 보고 싶다면 타입 매개변수에 대한 제약 조건 문서를 참고하세요.

더 알아보기