“T : class, new ()”는 무엇을 의미합니까?


답변:


329

이것은 일반 매개 변수에 대한 제약 조건입니다 T. 그것은해야합니다 class(참조 타입)과 공공 매개 변수가없는 기본 생성자가 있어야합니다.

방법 그 T될 수없는 int, float, double, DateTime또는 다른 struct(치형).

string기본 또는 매개 변수가없는 생성자 가있는 한 , 또는 다른 사용자 정의 참조 유형 일 수 있습니다 .


5
명확히하기 위해, where T ...의 일부로 class 절이 없다면 int, float, double 등을 사용하는 것이 안전합니다.
AboutDev

1
@AboutDev는 제네릭 형식 매개 변수에 제약 조건을 둘 필요가 없습니다. 그러나 참조 또는 값 유형에서만 작동하는 일반을 작성하는 경우 지정해야합니다. 제약 조건이 없으면 참조 유형 (클래스) 또는 값 유형 (구조 (int, float, double ...))을 기대할 수 있습니다.
NerdFury

1
T : [인터페이스 이름], new ()는 어떻습니까? 여전히 매개 변수가없는 생성자가 필요합니까?
빈스 티노

3
Justin의 의견을 명확히하기 위해 빈 생성자는 기본 생성자와 같은 명령문이 없지만 매개 변수가없는 생성자는 목록 초기화와 같은 명령문을 포함 할 수 있습니다.
DharmaTurtle

@VinceTino : new()정확하게 "공개 매개 변수없는 생성자가 있어야 함"을 정확하게 지정
Flater

162

이것들은 일반적인 타입 제약입니다. 귀하의 경우에는 두 가지가 있습니다.

where T : class

T유형이 값 유형이 아닌 참조 유형 이어야 함을 의미합니다 .

where T : new()

형식 T에 매개 변수가없는 생성자가 있어야 함을 의미합니다 . 이 제약 조건을 사용하면 T field = new T();코드에서 와 달리 다른 방법으로는 할 수없는 일을 할 수 있습니다.

그런 다음 쉼표를 사용하여 두 가지를 결합하여 얻을 수 있습니다.

where T : class, new()

두 번째와 세 번째에 대한 좋은 점은 정보를 추가하기 위해 두 번째 점이 일반 유형으로 반사 할 때 유용하다고 생각합니다. 예. T t = 새로운 T (); t.GetType (). GetProperty ( "ID"). SetValue (t, uniqueId, null);
Jerry Liang

1
구조체는 기본 생성자를 가질 수 없기 때문에 new ()는 이미 클래스를 암시하기 때문에 T : class, new ()는 말할 필요가 없다고 생각합니다.
DharmaTurtle

@DharmaTurtle은 "구조체에는 명시적인 매개 변수가없는 생성자를 포함 할 수 없습니다."라는 것이 아니라고 정의 할 수는 없습니다. 출처 : msdn.microsoft.com/tr-tr/library/aa288208(v=vs.71).aspx
rustem

121

여기서 T : 구조체

type 인수는 값 형식이어야합니다. Nullable을 제외한 모든 값 유형을 지정할 수 있습니다. 자세한 정보는 널 입력 가능 유형 사용 (C # 프로그래밍 안내서)을 참조하십시오.

여기서 T : 클래스

type 인수는 클래스, 인터페이스, 대리자 또는 배열 유형을 포함한 참조 유형이어야합니다. (아래 참고 참조)

여기서 T : new () 형식 인수에는 공용 매개 변수없는 생성자가 있어야합니다. 다른 제약 조건과 함께 사용하는 경우 new () 제약 조건을 마지막에 지정해야합니다.

여기서 T : [기본 클래스 이름]

type 인수는 지정된 기본 클래스에서 가져 오거나 파생되어야합니다.

여기서 T : [인터페이스 이름]

type 인수는 지정된 인터페이스이거나 지정된 인터페이스 여야합니다. 여러 인터페이스 제약 조건을 지정할 수 있습니다. 구속 인터페이스도 일반적 일 수 있습니다.

여기서 T : U

T에 제공되는 형식 인수는 U에 제공 한 인수에서 가져 오거나 파생되어야합니다.이를 나 체적 형식 제약 조건이라고합니다.


23
이것은 유용했지만 source 링크 입니다.
Skean

26

class& new제네릭 형식 매개 변수에 대한T 두 가지 제약 조건입니다 .
각각은 다음을 보장합니다.

class

형식 인수는 참조 형식이어야합니다. 이것은 모든 클래스, 인터페이스, 대리자 또는 배열 유형에도 적용됩니다.

new

형식 인수에는 공용 매개 변수없는 생성자가 있어야합니다. 다른 제약 조건과 함께 사용하는 경우 new () 제약 조건을 마지막에 지정해야합니다.

이들의 조합은 유형 T참조 유형 ( 유형일 수 없음 )이어야하고 매개 변수가없는 생성자가 있어야 함을 의미합니다.

예:

struct MyStruct { } // structs are value types

class MyClass1 { } // no constructors defined, so the class implicitly has a parameterless one

class MyClass2 // parameterless constructor explicitly defined
{
    public MyClass2() { }
}

class MyClass3 // only non-parameterless constructor defined
{
    public MyClass3(object parameter) { }
}

class MyClass4 // both parameterless & non-parameterless constructors defined
{
    public MyClass4() { }
    public MyClass4(object parameter) { }
}

interface INewable<T>
    where T : new()
{
}

interface INewableReference<T>
    where T : class, new()
{
}

class Checks
{
    INewable<int> cn1; // ALLOWED: has parameterless ctor
    INewable<string> n2; // NOT ALLOWED: no parameterless ctor
    INewable<MyStruct> n3; // ALLOWED: has parameterless ctor
    INewable<MyClass1> n4; // ALLOWED: has parameterless ctor
    INewable<MyClass2> n5; // ALLOWED: has parameterless ctor
    INewable<MyClass3> n6; // NOT ALLOWED: no parameterless ctor
    INewable<MyClass4> n7; // ALLOWED: has parameterless ctor

    INewableReference<int> nr1; // NOT ALLOWED: not a reference type
    INewableReference<string> nr2; // NOT ALLOWED: no parameterless ctor
    INewableReference<MyStruct> nr3; // NOT ALLOWED: not a reference type
    INewableReference<MyClass1> nr4; // ALLOWED: has parameterless ctor
    INewableReference<MyClass2> nr5; // ALLOWED: has parameterless ctor
    INewableReference<MyClass3> nr6; // NOT ALLOWED: no parameterless ctor
    INewableReference<MyClass4> nr7; // ALLOWED: has parameterless ctor
}

1
좋은 데모. 감사.
Subhan Ali

15

new () : new () 제약 조건을 지정하면 유형 T는 매개 변수가없는 생성자를 사용해야하므로 객체를 인스턴스화 할 수 있습니다 ( 기본 생성자 참조) .

class : 평균 T는 int, float, double, DateTime 또는 기타 구조체 (값 형식)가 될 수 없도록 참조 형식이어야합니다.

public void MakeCars()
{
    //This won't compile as researchEngine doesn't have a public constructor and so can't be instantiated.
    CarFactory<ResearchEngine> researchLine = new CarFactory<ResearchEngine>();
    var researchEngine = researchLine.MakeEngine();

    //Can instantiate new object of class with default public constructor
    CarFactory<ProductionEngine> productionLine = new CarFactory<ProductionEngine>();
    var productionEngine = productionLine.MakeEngine();
}

public class ProductionEngine { }
public class ResearchEngine
{
    private ResearchEngine() { }
}

public class CarFactory<TEngine> where TEngine : class, new()
{
    public TEngine MakeEngine()
    {
        return new TEngine();
    }
}

6

유형 것을 의미 T클래스이어야 하고 인수를 취하지 않는 생성자를 가지고있다.

예를 들어 다음을 수행 할 수 있어야합니다.

T t = new T();

1
생성자뿐만 아니라 인수를 사용하지 않는 생성자입니다.
NerdFury

@NerdFury : 감사합니다. 그것은 중요한 부분입니다. 수정했습니다.
Evan Mulawski

5

어디서 (C # Reference)

new () 제약 조건을 사용하면 제공된 모든 형식 인수에 액세스 가능한 매개 변수가없는 (또는 기본) 생성자가 있어야 함을 컴파일러에 알릴 수 있습니다.

따라서 T클래스이어야하고 액세스 가능한 매개 변수가없는 또는 기본 생성자가 있어야합니다.


4

"Where"뒤에 오는 것은 선언 한 제네릭 형식 T에 대한 제약 조건입니다.

  • class 는 T가 값 유형이나 구조체가 아닌 클래스 여야 함을 의미합니다.

  • new () 는 T 클래스에 공개 매개 변수가없는 기본 생성자가 정의되어 있어야 함을 나타냅니다.


1

일반 매개 변수 T에서 '제약'이라고합니다. 이는 T가 참조 유형 (클래스)이어야하고 공용 기본 생성자가 있어야 함을 의미합니다.


1

이것은 generics 메커니즘의 일부이며 where 키워드는 형식 매개 변수로 사용하기 위해 구현해야하는 형식에 제약 조건을 추가합니다.


0

제약 조건 에서 클래스 를 사용할 때 참조 유형 만 사용할 수 있다는 것을 의미합니다. 추가해야 할 또 다른 사항은 제약 조건 new () 를 사용할 때 제약 조건 에서 마지막으로 작성해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.