제약이 없는 형식 매개 변수 주석
메모
이 문서는 기능 사양입니다. 사양은 기능의 디자인 문서 역할을 합니다. 여기에는 기능 디자인 및 개발 중에 필요한 정보와 함께 제안된 사양 변경 내용이 포함됩니다. 이러한 문서는 제안된 사양 변경이 완료되고 현재 ECMA 사양에 통합될 때까지 게시됩니다.
기능 사양과 완료된 구현 간에 약간의 불일치가 있을 수 있습니다. 이러한 차이는 관련된LDM(언어 디자인 모임) 노트에 기록됩니다.
사양문서에서 C# 언어 표준에 기능 사양을 채택하는 과정에 대해 더 자세히 알아볼 수 있습니다.
챔피언 이슈: https://github.com/dotnet/csharplang/issues/3297
요약
값 형식 또는 참조 형식으로 제한되지 않는 형식 매개 변수에 대해 nullable 주석을 허용합니다. T?
.
static T? FirstOrDefault<T>(this IEnumerable<T> collection) { ... }
?
주석
C#8에서 ?
주석은 값 형식 또는 참조 형식으로 명시적으로 제한된 형식 매개 변수에만 적용할 수 있습니다.
C#9에서는 제약 조건에 관계없이 모든 형식 매개 변수에 ?
주석을 적용할 수 있습니다.
형식 매개 변수가 명시적으로 값 형식으로 제한되지 않는 한 주석은 #nullable enable
컨텍스트 내에서만 적용할 수 있습니다.
형식 매개 변수 T
참조 형식으로 대체되는 경우 T?
해당 참조 형식의 nullable 인스턴스를 나타냅니다.
var s1 = new string[0].FirstOrDefault(); // string? s1
var s2 = new string?[0].FirstOrDefault(); // string? s2
T
값 형식으로 대체되는 경우 T?
T
인스턴스를 나타냅니다.
var i1 = new int[0].FirstOrDefault(); // int i1
var i2 = new int?[0].FirstOrDefault(); // int? i2
T
주석이 추가된 형식 U?
대체되는 경우 T?
U??
대신 주석이 추가된 형식 U?
나타냅니다.
var u1 = new U[0].FirstOrDefault(); // U? u1
var u2 = new U?[0].FirstOrDefault(); // U? u2
T
이(가) U
의 유형으로 대체되면, T?
는 #nullable disable
컨텍스트 내에서도 U?
를 나타냅니다.
#nullable disable
var u3 = new U[0].FirstOrDefault(); // U? u3
반환 값의 경우 T?
[MaybeNull]T
; 인수 값의 경우 T?
[AllowNull]T
동일합니다.
C#8로 컴파일된 어셈블리에서 인터페이스를 재정의하거나 구현하는 경우 동등성이 중요합니다.
public abstract class A
{
[return: MaybeNull] public abstract T F1<T>();
public abstract void F2<T>([AllowNull] T t);
}
public class B : A
{
public override T? F1<T>() where T : default { ... } // matches A.F1<T>()
public override void F2<T>(T? t) where T : default { ... } // matches A.F2<T>()
}
default
제약 조건
기존 코드에서 재정의되거나 명시적으로 구현된 제네릭 메서드는 명시적 제약 조건 절을 포함할 수 없습니다. 따라서 값 형식인 T
에 대해 재정의되거나 명시적으로 구현된 메서드 내에서 T?
은 Nullable<T>
으로 처리됩니다.
참조 형식으로 제한되는 형식 매개 변수에 대한 주석을 허용하기 위해 C#8에서는 재정의되거나 명시적으로 구현된 메서드에서 명시적 where T : class
및 where T : struct
제약 조건을 허용했습니다.
class A1
{
public virtual void F1<T>(T? t) where T : struct { }
public virtual void F1<T>(T? t) where T : class { }
}
class B1 : A1
{
public override void F1<T>(T? t) /*where T : struct*/ { }
public override void F1<T>(T? t) where T : class { }
}
참조 형식 또는 값 형식으로 제한되지 않은 형식 매개 변수에 대한 주석을 허용하기 위해 C#9에서는 새 where T : default
제약 조건을 허용합니다.
class A2
{
public virtual void F2<T>(T? t) where T : struct { }
public virtual void F2<T>(T? t) { }
}
class B2 : A2
{
public override void F2<T>(T? t) /*where T : struct*/ { }
public override void F2<T>(T? t) where T : default { }
}
메서드 재정의 또는 명시적 구현 이외의 default
제약 조건을 사용하는 것은 오류입니다.
재정의되거나 인터페이스 메서드의 해당 형식 매개 변수가 참조 형식 또는 값 형식으로 제한될 때 default
제약 조건을 사용하는 것은 오류입니다.
디자인 회의
C# feature specifications