이 문서에서는 다음 컴파일러 오류를 다룹니다.
- CS0080: 제네릭이 아닌 선언에서는 제약 조건이 허용되지 않습니다.
- CS0081: 형식 매개 변수 선언은 형식이 아닌 식별자여야 합니다.
- CS0224: vararg를 사용하는 메서드는 제네릭이거나 제네릭 형식이거나 매개 변수가 있을 수 없습니다.
-
CS0304: 제약 조건이 없으므로 변수 형식의 인스턴스를
new()만들 수 없습니다. - CS0305: 제네릭 형식을 사용하려면 N 형식 인수가 필요합니다.
- CS0306: 형식을 형식 인수로 사용할 수 없습니다.
- CS0307: 식별자가 제네릭 메서드가 아닙니다. 식 목록을 의도한 경우 식 주위에 괄호를 사용합니다.
- CS0308: 제네릭이 아닌 형식 또는 메서드는 형식 인수와 함께 사용할 수 없습니다.
- CS0310: 형식을 제네릭 형식 또는 메서드의 매개 변수로 사용하려면 공용 매개 변수가 없는 생성자가 있는 비 추상 형식이어야 합니다.
-
CS0311: 제네릭 형식 또는 메서드에서 형식 매개 변수
T로 형식을 사용할 수 없습니다. type1에서 type2로의 암시적 참조 변환은 없습니다. - CS0312: 'type1' 형식은 제네릭 형식 또는 메서드에서 형식 매개 변수로 사용할 수 없습니다. nullable 형식 'type1'이 제약 조건을 충족하지 않습니다.
- CS0313: 'type1' 형식은 제네릭 형식 또는 메서드에서 형식 매개 변수로 사용할 수 없습니다. nullable 형식 'type1'이 제약 조건을 충족하지 않습니다. Nullable 형식은 인터페이스 제약 조건을 충족할 수 없습니다.
- CS0314: 형식을 제네릭 유형이나 메서드의 형식 매개 변수로 사용할 수 없습니다. 박싱 변환이나 형식 매개 변수 변환이 존재하지 않습니다.
-
CS0315: 제네릭 형식 또는 메서드에서 형식 매개 변수
T로 형식을 사용할 수 없습니다. 권투 변환은 없습니다. -
CS0401: 제약 조건이
new()지정된 마지막 제약 조건이어야 합니다. -
CS0403: null이 아닌 값 형식일 수 있으므로 null을 형식 매개 변수로 변환할 수 없습니다. 대신 사용하는
default(T)것이 좋습니다. - CS0405: 형식 매개 변수에 대한 중복 제약 조건입니다.
- CS0412: 매개 변수: 매개 변수, 지역 변수 또는 로컬 함수는 메서드 형식 매개 변수와 같은 이름을 가질 수 없습니다.
-
CS0413: 클래스 형식 제약 조건이나
as제약 조건이 없으므로 형식 매개 변수를 연산자에 사용할class수 없습니다. - CS0417: 식별자: 변수 형식의 인스턴스를 만들 때 인수를 제공할 수 없습니다.
-
CS0449:
class,struct, ,unmanagednotnull및default제약 조건은 결합하거나 복제할 수 없으며 제약 조건 목록에서 먼저 지정해야 합니다. -
CS0450: 형식 매개 변수: 제약 조건 클래스와
class제약struct조건을 둘 다 지정할 수 없습니다. -
CS0451: 제약 조건을
new()제약 조건과 함께struct사용할 수 없습니다. - CS0454: 형식 매개 변수 1 및 형식 매개 변수 2와 관련된 순환 제약 조건 종속성입니다.
- CS0455: 형식 매개 변수는 충돌하는 제약 조건을 상속합니다.
- CS0694: 형식 매개 변수의 이름은 포함하는 형식 또는 메서드와 같습니다.
-
CS0695:
T일부 형식 매개 변수 대체에 대해 통합될 수 있으므로 두 인터페이스를 모두 구현할 수 없습니다. - CS0698: 제네릭 형식은 특성 클래스이므로 형식에서 파생될 수 없습니다.
- CS0702: 제약 조건은 특수 클래스일 수 없습니다.
- CS0703: 일관성 없는 접근성: 제약 조건 형식은 선언보다 접근성이 떨어집니다.
- CS0706: 잘못된 제약 조건 형식입니다. 제약 조건으로 사용되는 형식은 인터페이스, 봉인되지 않은 클래스 또는 형식 매개 변수여야 합니다.
- CS0717: 정적 클래스: 정적 클래스를 제약 조건으로 사용할 수 없습니다.
- CS1961: 잘못된 분산: 형식 매개 변수는 형식에서 유효한 변형이어야 합니다.
- CS7002: 제네릭 이름을 예기치 않게 사용했습니다.
- CS8322: 동적 형식의 인수를 유추된 형식 인수를 사용하여 제네릭 로컬 함수에 전달할 수 없습니다.
-
CS9011: 키워드
delegate를 제약 조건으로 사용할 수 없습니다.System.Delegate를 의미하셨습니까? -
CS9012: 예기치 않은 키워드
record.record struct또는record class중 하나를 의미하셨습니까? - CS9338: 일관성 없는 접근성: 형식은 클래스보다 접근성이 떨어집니다.
형식 매개 변수 선언 및 명명
다음 오류는 제네릭 형식 및 메서드에서 형식 매개 변수를 선언하고 이름을 지정하는 방법과 관련이 있습니다.
- CS0080: 제네릭이 아닌 선언에서는 제약 조건이 허용되지 않습니다.
- CS0081: 형식 매개 변수 선언은 형식이 아닌 식별자여야 합니다.
- CS0412: 매개 변수: 매개 변수, 지역 변수 또는 로컬 함수는 메서드 형식 매개 변수와 같은 이름을 가질 수 없습니다.
- CS0694: 형식 매개 변수의 이름은 포함하는 형식 또는 메서드와 같습니다.
-
CS9012: 예기치 않은 키워드
record.record struct또는record class를 의미하셨습니까?
이러한 오류를 수정하려면 유효한 식별자를 사용하여 형식 매개 변수를 선언하고, 제네릭 선언에만 제약 조건 절을 적용하고, 범위의 다른 식별자와 명명 충돌을 피해야 합니다.
- 제네릭이 아닌 선언(CS0080)에서 제약 조건 절을 제거합니다.
where제약 조건은 형식 인수가 충족해야 하는 요구 사항을 정의하기 때문에 형식 매개 변수를 선언하는 제네릭 형식 및 메서드에서만 절을 사용할 수 있습니다. 제약 조건을 적용해야 하는 경우 먼저 형식 또는 메서드 선언에 형식 매개 변수를 추가합니다. 예를 들어public class MyClass where MyClass : System.IDisposable를public class MyClass<T> where T : System.IDisposable로 변경합니다. - 실제 형식 이름을 형식 매개 변수 선언의 식별자(CS0081)로 대체합니다. 구체적인 형식(예
TTKey: 또는 )이 아닌 식별자(예:TValueint또는string)를 사용하여 형식 매개 변수를 선언해야 합니다. 형식 매개 변수의 목적은 제네릭 형식 또는 메서드를 사용할 때 컴파일러가 실제 형식으로 대체하는 자리 표시자 역할을 하는 것입니다. 예를 들어public void F<int>()를public void F<T>()로 변경합니다. - 이름 충돌을 방지하기 위해 형식 매개 변수, 지역 변수 또는 매개 변수의 이름을 바꿉니다(CS0412, CS0694). 형식 매개 변수 이름은 동일한 범위에서 식별자를 섀도할 수 없습니다. 포함하는 형식 또는 메서드의 이름과 일치시킬 수 없습니다. 이러한 충돌은 참조되는 식별자에 대한 모호성을 만듭니다. 예를 들어 메서드
public void F<T>()가 있을 때 해당 메서드에서 지역 변수double T를 선언할 수 없으며, 형식 매개변수의 이름을 포함하는 형식class C<C>과 동일하게 지정할 수 없습니다. - 올바른 레코드 선언 구문(CS9012)을 사용합니다. 레코드 형식을 선언할 때,
record class또는record struct를 사용해야 하며, 참조 형식의 경우는record만 사용할 수 있습니다.record키워드만 컴파일러에서 형식 선언 구문을 예상하는 위치에는 표시할 수 없습니다. 예를 들어, 레코드 형식을 선언하려는 경우에는 다른 키워드가 필요한 위치에record를 놓는 대신record class MyRecord또는record struct MyRecord를 작성하십시오.
자세한 내용은 제네릭 형식 매개 변수 및 제네릭을 참조하세요.
제약 조건 선언 및 순서 지정
다음 오류는 제네릭 형식 매개 변수에 대한 제약 조건의 구문 및 순서와 관련이 있습니다.
-
CS0401: 제약 조건이
new()지정된 마지막 제약 조건이어야 합니다. -
CS0449:
class,struct, ,unmanagednotnull및default제약 조건은 결합하거나 복제할 수 없으며 제약 조건 목록에서 먼저 지정해야 합니다. -
CS0450: 형식 매개 변수: 제약 조건 클래스와
class제약struct조건을 둘 다 지정할 수 없습니다. -
CS0451:
new()제약 조건은struct제약 조건과 함께 사용할 수 없습니다. -
CS9011: 키워드
delegate를 제약 조건으로 사용할 수 없습니다. 혹시System.Delegate를 의미하셨습니까?
형식 매개 변수에 대한 제약 조건은 특정 순서를 따라야 합니다. 기본 제약 조건(, , , classstruct또는unmanaged)이 먼저 오고, 인터페이스 또는 클래스 제약 조건이 뒤따르고, 마지막으로 notnull 생성자 제약 조건이 와야 합니다. defaultnew() 일부 제약 조건은 함께 사용할 수 없으며 결합할 수 없습니다.
이러한 오류를 수정하려면 다음을 수행합니다.
- 제약 조건
new()목록의 끝에 제약 조건을 배치합니다(CS0401). 제약 조건은new()다른 모든 제약 조건 후에 나타나야 합니다. 예를 들어where T : new(), IDisposable를where T : IDisposable, new()로 변경합니다. - 주 제약 조건을 먼저 배치하고 상호 배타적 제약 조건(CS0449)을 결합하지 마세요. , ,
classstructunmanaged또는notnull중 하나default만 지정할 수 있으며 제약 조건 목록에 먼저 나타나야 합니다.class및struct제약 조건은 상호 배타적이며,class및unmanaged도 마찬가지입니다. nullable 컨텍스트class에서는 이미notnull을(를) 의미하므로 결합할 수 없습니다. - 특정 클래스 제약 조건을 (
struct)와 결합하지 마세요. 형식 매개 변수가 특정 클래스 형식으로 제한되는 경우 암시적으로 제약 조건과struct모순되는 참조 형식입니다. 클래스 제약 조건 또는struct제약 조건 중 하나를 제거하십시오. -
new()와struct를 결합하지 마세요 (CS0451). 모든 값 형식(구조체)에는 암시적으로 공용 매개 변수 없는 생성자가 있으므로new()제약 조건과struct결합하면 중복됩니다.new()제약 조건을struct사용할 때 제거합니다. - 제약 조건 절(CS9011)에서
delegate을System.Delegate으로 대체합니다. 키워드delegate는 제약 조건으로 사용되지 않고 대리자 형식을 선언하기 위해 사용됩니다. 형식 매개 변수를 위임 형식으로 제한하려면 제약 조건 형식으로 사용합니다System.Delegate. 예를 들어where T : delegate를where T : System.Delegate로 변경합니다.
다음 예제에서는 올바른 제약 조건 순서를 보여줍니다.
using System;
// Primary constraint first, then interface constraints, then new()
class C<T> where T : class, IDisposable, new() { }
// struct doesn't need new() - it's implicit
class D<T> where T : struct, IComparable { }
// Delegate constraint using System.Delegate
class E<T> where T : System.Delegate { }
자세한 내용은 형식 매개 변수에 대한 제약 조건을 참조하세요.
형식 인수 수 및 사용량
다음 오류는 제네릭 형식 및 메서드에 올바른 형식 인수의 수와 형식을 제공하는 것과 관련이 있습니다.
- CS0224: vararg를 사용하는 메서드는 제네릭이거나 제네릭 형식이거나 매개 변수가 있을 수 없습니다.
- CS0305: 제네릭 형식을 사용하려면 N 형식 인수가 필요합니다.
- CS0306: 형식을 형식 인수로 사용할 수 없습니다.
- CS0307: 식별자가 제네릭 메서드가 아닙니다. 식 목록을 의도한 경우 식 주위에 괄호를 사용합니다.
- CS0308: 제네릭이 아닌 형식 또는 메서드는 형식 인수와 함께 사용할 수 없습니다.
- CS7002: 제네릭 이름을 예기치 않게 사용했습니다.
이러한 오류를 수정하려면 제네릭 선언에 필요한 형식 인수의 정확한 수를 제공해야 합니다. 형식 인수로 유효한 형식만 사용합니다. 제네릭이 아닌 구문에는 형식 인수를 적용하지 마세요.
-
__arglist를 사용하는 메서드(CS0224)에서 제네릭 형식 매개 변수 또는 포함된 제네릭 형식 선언을 제거합니다.__arglist변수 인수 목록을 처리하기 위한 런타임 메커니즘이 제네릭 형식 매개 변수에 필요한 형식 대체와 충돌하기 때문에 키워드는 제네릭과 호환되지 않습니다. 이 제한은 제네릭 형식 내의params제네릭 메서드 또는 메서드와 함께 사용하는 경우에도 키워드에 적용됩니다. - 제네릭 형식 또는 메서드 선언(CS0305)에 지정된 형식 인수의 정확한 수를 제공합니다. 정의에 선언된 각 제네릭 형식 매개 변수에는 제네릭 형식이 인스턴스화될 때 해당 형식 인수가 있어야 합니다. 컴파일러는 각 형식 매개 변수를 대체할 구체적인 형식을 알아야 합니다. 예를 들어, 클래스가
class MyList<T>로 선언된 경우, 이를 사용할 때 정확히 하나의 형식 인수를 제공해야 합니다. 예를 들어MyList<int>와 같이 사용하고,MyList<int, string>는 사용하지 않아야 합니다. - 형식 인수로 유효한 형식만 사용합니다(CS0306). 제네릭 형식에는 가비지 수집기가 추적할 수 있는 관리되는 형식이 필요하고 포인터 형식은 관리되지 않으므로 형식 인수와 같은
int*char*포인터 형식을 사용할 수 없습니다. 제네릭 컨텍스트에서 포인터를 사용해야 하는 경우 제네릭을 안전하지 않은 코드와 혼합하지 않도록 코드를 사용IntPtr하거나 재구성하는 것이 좋습니다. - 제네릭이 아닌 구문(CS0307, CS0308)에서 형식 인수 구문을 제거합니다. 꺾쇠 괄호로 묶인 형식 인수(예:
<int>)는 형식 매개 변수를 선언하는 제네릭 형식 및 메서드에만 적용할 수 있습니다. 형식 인수를 완전히 제거하거나 형식의 제네릭 버전이 포함된 네임스페이스를 가져왔어야 합니다. 예를 들어IEnumerator<T>지시문을using System.Collections.Generic;에 필요로 하는 반면IEnumerator는System.Collections에 있습니다. - 제네릭을 지원하지 않는 선언에서 형식 매개 변수를 제거합니다(CS7002). 열거형과 같은 일부 구문은 제네릭일 수 없습니다. 열거형 값에 제네릭 컨테이너가 필요한 경우 제네릭 클래스 또는 구조체를 대신 사용하는 것이 좋습니다.
자세한 내용은 제네릭 형식 매개 변수 및 제네릭을 참조하세요.
생성자 제약 조건
다음 오류는 제네릭 형식 매개 변수의 new() 제약 조건과 관련이 있습니다.
-
CS0304: 제약 조건이 없으므로 변수 형식의 인스턴스를
new()만들 수 없습니다. - CS0310: 형식을 제네릭 형식 또는 메서드의 매개 변수로 사용하려면 공용 매개 변수가 없는 생성자가 있는 비 추상 형식이어야 합니다.
- CS0417: 식별자: 변수 형식의 인스턴스를 만들 때 인수를 제공할 수 없습니다.
이러한 오류를 수정하려면 인스턴스화해야 하는 형식 매개 변수에 제약 조건을 추가하고 new() , 형식 인수에 공용 매개 변수가 없는 생성자가 있는지 확인하고, 형식 매개 변수 인스턴스를 생성할 때 인수를 전달하지 않도록 합니다.
-
new()형식 매개 변수 선언(CS0304)에 제약 조건을 추가합니다. 연산자를new사용하여 제네릭 형식 또는 메서드 내에서 형식 매개 변수의 인스턴스를 만드는 경우 컴파일러는 런타임에 제공된 모든 형식 인수에 매개 변수가 없는 생성자를 사용할 수 있도록 보장할 수 있어야 합니다. 제약 조건은new()컴파일 시간에 이 보장을 제공하므로 컴파일러가 적절한 인스턴스화 코드를 생성할 수 있습니다. 예를 들어,class C<T>에T t = new T();멤버가 있는 경우 선언을class C<T> where T : new()으로 변경해야 합니다. - 제한된 형식 매개 변수와 함께
new()사용되는 형식 인수에 공용 매개 변수가 없는 생성자(CS0310)가 있는지 확인합니다. 제네릭 형식 또는 메서드가 형식 매개 변수에 대한 제약 조건을 선언new()하는 경우 형식 인수로 사용되는 구체적인 형식은 비 추상 형식이어야 하며 공용 매개 변수가 없는 생성자를 제공해야 합니다. 형식에 public이 아닌 생성자(예:privateprotected생성자)만 있거나 매개 변수가 있는 생성자만 있는 경우 제약 조건을new()충족할 수 없습니다. 이 오류를 해결하려면 매개 변수가 없는 공용 생성자를 형식에 추가하거나 이미 있는 다른 형식 인수를 사용합니다. - 형식 매개 변수를 인스턴스화할 때 생성자 인수를 제거합니다(CS0417). 제약 조건은
new()매개 변수가 없는 생성자의 존재만 보장하므로 컴파일러가 해당 특정 매개 변수 형식을 가진 생성자가 대체되는new T(arguments)형식에 있는지 확인할 수 없으므로 인수T를 전달할 수 없습니다. 특정 인수를 사용하여 인스턴스를 생성해야 하는 경우 팩터리 메서드, 추상 팩터리 패턴 또는 필요한 생성 동작을 정의하는 특정 기본 클래스 또는 인터페이스 제약 조건을 사용하는 것이 좋습니다.
자세한 내용은 형식 매개 변수 및 제약 조건에 대한제약 조건을new() 참조하세요.
제약 조건 만족도 및 변환
다음 오류는 제네릭 형식 매개 변수의 제약 조건을 충족하지 않는 형식 인수와 관련이 있습니다.
-
CS0311: 제네릭 형식 또는 메서드에서 형식 매개 변수
T로 형식을 사용할 수 없습니다. 암시적 참조 변환은 없습니다. - CS0312: 제네릭 형식 또는 메서드에서 형식 매개 변수로 형식을 사용할 수 없습니다. nullable 형식이 제약 조건을 충족하지 않습니다.
- CS0313: 제네릭 형식 또는 메서드에서 형식 매개 변수로 형식을 사용할 수 없습니다. nullable 형식이 제약 조건을 충족하지 않습니다. Nullable 형식은 인터페이스 제약 조건을 충족할 수 없습니다.
- CS0314: 제네릭 형식 또는 메서드에서 형식 매개 변수로 이 형식을 사용할 수 없습니다. 박싱 변환이나 형식 매개 변수 변환이 존재하지 않습니다.
-
CS0315: 제네릭 형식 또는 메서드
T에서 형식 매개 변수TypeorMethod<T>로 형식을 사용할 수 없습니다. 권투 변환은 없습니다.
이러한 오류를 수정하려면 적절한 변환을 통해 모든 제약 조건을 충족하는 형식 인수를 사용하고, 파생 클래스가 기본 클래스 제약 조건을 반복하고, nullable 값 형식에 특별한 제약 조건 요구 사항이 있음을 이해합니다.
- 형식 인수를 제약 조건 형식(CS0311)으로 암시적 참조 변환이 있는 인수로 변경합니다. 형식 매개 변수에
where T : BaseType와 같은 제약 조건이 있는 경우, 모든 형식 인수는 암시적 참조 변환 또는 항등 변환을 통해BaseType로 변환될 수 있어야 합니다. 형식 인수는BaseType자체이거나BaseType에서 파생되거나, 인터페이스인 경우BaseType를 구현해야 합니다. 암시적 숫자 변환(예: 원본shortint)은 제네릭 형식 매개 변수 제약 조건을 충족하지 않습니다. 이러한 변환은 참조 변환이 아니라 값 변환이기 때문입니다. - 파생 클래스 선언(CS0314)에서 기본 클래스의 형식 매개 변수 제약 조건을 반복합니다. 파생 제네릭 클래스가 해당 형식 매개 변수에 대한 제약 조건이 있는 기본 제네릭 클래스에서 상속되는 경우 파생 클래스는 해당 형식 매개 변수에 대해 동일한 제약 조건을 선언해야 합니다. 컴파일러가 파생 클래스에 제공된 형식 인수가 기본 클래스의 요구 사항을 충족하는지 확인해야 하므로 이러한 제약 조건을 반복해야 합니다. 예를 들어
public class A<T> where T : SomeClass가 있는 경우, 그것으로부터 파생되는 모든 클래스는public class B<T> : A<T> where T : SomeClass로 선언해야 합니다. - nullable이 아닌 값 형식을 사용하거나 제약 조건 형식(CS0312, CS0313)을 변경합니다. Nullable 값 형식(예:
int?)은 기본 값 형식과 구별되며 동일한 제약 조건을 충족하지 않습니다.int?및int간에는 암시적 변환이 없으며, nullable 값 형식은 기본 값 형식이 인터페이스를 구현하더라도 nullable 래퍼 자체가 인터페이스를 구현하지 않기 때문에 인터페이스 제약 조건을 충족할 수 없습니다. 이러한 오류를 수정하려면 값 형식의 non-nullable 형식을 형식 인수로 사용하거나 제약 조건을object이나 nullable 참조 형식을 수용하도록 적절히 조정하세요. - 형식 인수가 참조 형식 또는 클래스 제약 조건(CS0315)을 충족하는지 확인합니다. 형식 매개 변수가 클래스 형식(예:
where T : SomeClass)으로 제한되는 경우 제약 조건 관계를 충족하는 boxing 변환이 없기 때문에 값 형식(구조체)을 형식 인수로 사용할 수 없습니다. 제약 조건에는 제약 조건 형식과 상속 또는 구현 관계가 있는 참조 형식이 필요합니다. 이 오류를 해결하려면 의미상 적절한 경우 구조체를 클래스로 변경하거나 제네릭 형식이 값 형식에서 작동할 수 있는 경우 클래스 제약 조건을 제거합니다.
자세한 내용은 형식 매개 변수 및 암시적 변환에 대한 제약 조건을 참조하세요.
제네릭 형식 사용 제한
다음 오류는 제네릭 형식을 사용하는 방법에 대한 제한 사항과 관련이 있습니다.
-
CS0403: null이 아닌 값 형식일 수 있으므로 null을 형식 매개 변수로 변환할 수 없습니다. 대신 사용하는
default(T)것이 좋습니다. -
CS0413: 형식 매개 변수를
as연산자와 함께 사용할 수 없습니다. 이는 해당 형식 매개 변수가 클래스 형식 제약 조건이나class제약 조건이 없기 때문입니다. - CS0695: 형식은 두 인터페이스를 모두 구현할 수 없으며 일부 형식 매개 변수 대체에 대해 통합될 수 있기 때문입니다.
- CS0698: 제네릭 형식은 특성 클래스이므로 형식에서 파생될 수 없습니다.
- CS8322: 동적 형식의 인수를 유추된 형식 인수를 사용하여 제네릭 로컬 함수에 전달할 수 없습니다.
- CS9338: 일관성 없는 접근성: 형식은 클래스보다 접근성이 떨어집니다.
이러한 오류를 수정하려면 제약이 없는 형식 매개 변수 대신 default 사용하고null, 연산자를 사용할 as 때 클래스 제약 조건을 추가하고, 인터페이스 통합 충돌을 방지하고, 제네릭 특성 클래스를 만들지 않고, 형식 인수가 포함된 멤버의 표시 유형과 일치하는지 확인합니다.
-
null할당을default(T)로 교체하거나class제약 조건을 추가하십시오(CS0403). 제약이 없는 형식 매개 변수에null을 할당하는 경우, 컴파일러는 형식 인수가null값을 허용하는 참조 형식임을 보장할 수 없습니다. 이는 값 형식인int또는struct가null될 수 없는 때문입니다. 이 오류를 해결하려면 모든 형식에 적절한 기본값(참조 형식의 경우 null, 값 형식의 경우 0 또는 비어 있음)을 사용default(T)하거나, 특히 참조 형식 의미 체계가 필요하고 할당을 허용class하려는 경우 형식 매개 변수에 제약 조건을 추가null합니다. -
class연산자를 사용할 때as또는 특정 형식 제약 조건을 추가하십시오(CS0413).as연산자는 변환이 실패할 경우null를 반환하는 안전한 형식 캐스트를 수행하지만, 값 형식에는 이 동작이 호환되지null않습니다. 제약이 없는 형식 매개 변수와 함께 사용하는as경우 컴파일러는 형식 인수가 값 형식이 아님을 보장할 수 없으므로 코드를 거부합니다. 이 오류를 해결하려면 제약 조건 또는 특정 참조 형식 제약 조건(예:class)을 추가하여where T : SomeClass형식 매개 변수가 항상 실패한 캐스트의 결과를 제대로 처리null할 수 있는 참조 형식인지 확인합니다. - 통합할 수 있는 형식 매개 변수를 사용하여 동일한 제네릭 인터페이스를 여러 번 구현하지 마세요(CS0695). 클래스가 서로 다른 형식 매개 변수와 함께
class G<T1, T2> : I<T1>, I<T2>를 사용하여 제네릭 인터페이스를 여러 번 구현하는 경우, 두 매개 변수(G<int, int>)에 대해 동일한 형식으로 인스턴스화할 위험이 있으며, 이로 인해 클래스가 실질적으로I<int>을 두 번 구현하게 되어 충돌이 발생합니다. 이 오류를 해결하려면 인터페이스를 한 번만 구현하거나, 형식 매개 변수를 재구성하여 통합을 방지하거나, 다른 특수화에 별도의 비 제네릭 클래스를 사용합니다. - 특성 클래스에서 제네릭 형식 매개 변수를 제거합니다(CS0698).
비고
제네릭 특성이 지원되기 때문에 이 오류는 현재 버전의 C#에서 생성되지 않습니다.
- 동적 값을 제네릭 로컬 함수(CS8322)에 전달할 때 형식 인수를 명시적으로 지정합니다. 제네릭 로컬 함수에 인수를 전달
dynamic하면 런타임까지 실제 형식을 알 수 없으므로 컴파일러는 형식 인수를 유추할 수 없습니다. 이 오류를 해결하려면 형식 인수(예LocalFunc<int>(d): 형식 인수)를 명시적으로 지정하거나, 동적 값을 예상 형식으로 캐스팅하거나, 비동기 변수를 사용합니다. - 공용 또는 보호된 서명에 사용되는 형식 인수가 최소한 해당 인수를 사용하는 멤버만큼 액세스할 수 있는지 확인합니다(CS9338). 공용 또는 보호된 제네릭 멤버는 공개적으로 액세스할 수 있는 형식 인수를 사용해야 합니다. 그렇지 않으면 외부 코드가 멤버의 서명을 제대로 참조하거나 사용할 수 없습니다. 예를 들어
public class Container<T>에 내부 형식이 있는 경우, 외부 어셈블리는T는 볼 수 있지만Container는 볼 수 없기 때문에 올바르게 작동할 수 없습니다. 이 오류를 해결하려면 형식 인수를 공개로 설정하거나 형식 인수의 접근성과 일치하도록 멤버의 접근성을 줄입니다.
자세한 내용은 형식 매개 변수, 기본값 식 및 특성에 대한 제약 조건을 참조하세요.
유효한 제약 조건 형식
다음 오류는 제네릭 형식 매개 변수에 잘못된 형식을 제약 조건으로 사용하는 것과 관련이 있습니다.
- CS0405: 형식 매개 변수에 대한 중복 제약 조건입니다.
- CS0702: 제약 조건은 특수 클래스일 수 없습니다.
- CS0703: 일관성 없는 접근성: 제약 조건 형식은 선언보다 접근성이 떨어집니다.
- CS0706: 잘못된 제약 조건 형식입니다. 제약 조건으로 사용되는 형식은 인터페이스, 봉인되지 않은 클래스 또는 형식 매개 변수여야 합니다.
-
CS0717:
static class정적 클래스는 제약 조건으로 사용할 수 없습니다.
제약 조건은 인터페이스, 봉인되지 않은 클래스 또는 형식 매개 변수여야 합니다. 특정 형식은 .NET 형식 시스템에서 특별한 의미가 있거나 상속될 수 없기 때문에 제약 조건으로 유효하지 않습니다.
이러한 오류를 수정하려면 다음을 수행합니다.
- 중복 제약 조건 제거(CS0405). 각 제약 조건은 제약 조건 절에 한 번만 나타날 수 있습니다.
where T : I, I가 있는 경우, 중복 항목을 제거하십시오. - 특수 클래스를 제약 조건으로 사용하지 마세요(CS0702). 형식ObjectArray이며 ValueType 제약 조건으로 사용할 수 없습니다. 모든 형식은
Object이미 파생되므로 이를 제한하면 값이 없습니다.Array와ValueType는 직접 상속할 수 없는 추상 기본 형식입니다. 배열과 유사한 동작이 필요한 경우IList<T>또는IEnumerable<T>을 사용하십시오. - 제약 조건 형식이 제네릭 형식(CS0703)만큼은 최소한 액세스할 수 있는지 확인합니다. 외부 코드는 유효한 형식 인수를 제공할 수 없으므로 공용 제네릭 형식에는 내부 형식을 사용하는 제약 조건이 있을 수 없습니다. 제약 조건 형식을 공용으로 설정하거나 제네릭 형식의 접근성을 줄입니다.
- 인터페이스, 봉인되지 않은 클래스 또는 형식 매개 변수만 제약 조건으로 사용합니다(CS0706). 배열, 봉인된 클래스, 구조체, 열거형 또는 기타 잘못된 형식을 제약 조건으로 사용할 수 없습니다. 특정 동작이 필요한 경우 원하는 형식이 구현하는 인터페이스를 사용하는 것이 좋습니다.
- 정적 클래스를 제약 조건으로 사용하지 마세요(CS0717). 정적 클래스는 정적 멤버만 포함하므로 확장할 수 없습니다. 정적 클래스에서 파생되는 형식이 없어 제약 조건으로 사용할 수 없습니다. 대신 비정적 클래스 또는 인터페이스를 사용합니다.
다음 예제에서는 유효한 제약 조건 유형을 보여줍니다.
public interface IMyInterface { }
public class MyBaseClass { }
// Valid: interface constraint
class A<T> where T : IMyInterface { }
// Valid: non-sealed class constraint
class B<T> where T : MyBaseClass { }
// Valid: type parameter constraint
class C<T, U> where T : U { }
자세한 내용은 형식 매개 변수에 대한 제약 조건을 참조하세요.
제약 조건 충돌 및 순환 종속성
다음 오류는 제약 조건 선언의 제약 조건 또는 순환 종속성 간의 충돌과 관련이 있습니다.
- CS0454: 형식 매개 변수 1 및 형식 매개 변수 2와 관련된 순환 제약 조건 종속성입니다.
- CS0455: 형식 매개 변수는 충돌하는 제약 조건을 상속합니다.
제약 조건은 순환 종속성을 만들 수 없으며 형식 매개 변수는 동시에 충족할 수 없는 충돌하는 제약 조건을 상속할 수 없습니다.
이러한 오류를 수정하려면 다음을 수행합니다.
- 순환 제약 조건 종속성을 제거합니다(CS0454). 형식 매개 변수는 제약 조건을 통해 직접 또는 간접적으로 자체적으로 의존할 수 없습니다. 예를 들어,
where T : U where U : T는T가U에 의존하고U가T에 의존하기 때문에 순환 종속성을 만듭니다. 제약 조건 중 하나를 제거하여 주기를 중단합니다. - 충돌하는 상속된 제약 조건(CS0455)을 제거합니다. C#은 여러 클래스 상속을 지원하지 않으므로 형식 매개 변수를 관련 없는 여러 클래스로 제한할 수 없습니다. 마찬가지로,
struct및 클래스 형식 중 하나로만 제한될 수 있으며, 두 제약 조건은 상호 배타적입니다. 형식 계층 구조를 재구성하거나 충돌하는 제약 조건 중 하나를 제거합니다.
다음 예제에서는 문제를 보여 줍니다.
// CS0454: Circular dependency - T depends on U and U depends on T
class Circular<T, U> where T : U where U : T { }
// CS0455: Conflicting constraints - U can't derive from both B and B2
public class B { }
public class B2 { }
public class G<T> where T : B
{
public class N<U> where U : B2, T { }
}
자세한 내용은 형식 매개 변수에 대한 제약 조건을 참조하세요.
타입 매개 변수 분산
다음 오류는 제네릭 형식 매개 변수의 분산 한정자와 관련이 있습니다.
- CS1961: 잘못된 분산: 형식 매개 변수는 형식에서 유효한 공변이어야 합니다.
분산 한정자(in 반공변성, out 공변성)는 인터페이스 및 대리자 선언에서 형식 매개 변수를 사용하는 방법을 제어합니다. 공변(out) 형식 매개 변수는 출력 위치(반환 형식)에만 나타날 수 있지만 반공변(in) 형식 매개 변수는 입력 위치(매개 변수 형식)에만 나타날 수 있습니다.
이 오류를 해결하려면 다음을 수행합니다.
- 반환 형식에만 표시되는 형식 매개 변수에 (공변성)을 사용합니다
out. 공변성에서는 덜 파생된 형식이 필요한 경우 더 많은 파생 형식을 사용할 수 있습니다. - 매개변수 형식에만 표시되는 형식 매개 변수에는
in(반공변성)을 사용합니다. 반공변성은 더 파생된 형식이 기대되는 곳에서 덜 파생된 형식을 사용할 수 있게 해줍니다. - 형식 매개 변수가 입력 및 출력 위치 모두에 나타나야 하는 경우 분산 한정자를 제거합니다.
다음 예제에서는 정확하고 잘못된 분산 사용량을 보여 줍니다.
// Incorrect: out T can't appear in input position
interface IWrong<out T>
{
void Method(T arg); // CS1961
}
// Correct: out T only in output positions
interface ICovariant<out T>
{
T GetValue();
}
// Correct: in T only in input positions
interface IContravariant<in T>
{
void Process(T arg);
}
// No modifier needed for both input and output
interface IInvariant<T>
{
T Transform(T arg);
}
.NET