C# 11의 새로운 기능

C# 11에는 다음 기능이 추가되었습니다.

C# 11은 .NET 7에서 지원됩니다. 자세한 내용은 C# 언어 버전 관리를 참조하세요.

.NET 다운로드 페이지에서 최신 .NET 7 SDK를 다운로드할 수 있습니다. .NET 7 SDK를 포함하는 Visual Studio 2022를 다운로드할 수도 있습니다.

참고 항목

이러한 기능에 대한 사용자의 피드백을 환영합니다. 이러한 새로운 기능과 관련된 문제를 발견하면 dotnet/roslyn 리포지토리에서 새 문제를 만듭니다.

일반 특성

기본 클래스가 System.Attribute제네릭 클래스를 선언할 수 있습니다. 이 기능은 System.Type 매개 변수가 필요한 특성에 대해 보다 편리한 구문을 제공합니다. 이전에는 Type을 생성자 매개 변수로 사용하는 특성을 만들어야 했습니다.

// Before C# 11:
public class TypeAttribute : Attribute
{
   public TypeAttribute(Type t) => ParamType = t;

   public Type ParamType { get; }
}

그리고 특성을 적용하려면 typeof 연산자를 사용합니다.

[TypeAttribute(typeof(string))]
public string Method() => default;

이 새로운 기능을 사용하여 제네릭 특성을 대신 만들 수 있습니다.

// C# 11 feature:
public class GenericAttribute<T> : Attribute { }

그런 다음, 특성을 사용할 형식 매개 변수를 지정합니다.

[GenericAttribute<string>()]
public string Method() => default;

특성을 적용할 때 모든 형식 매개 변수를 제공해야 합니다. 즉, 제네릭 형식은 완전히 생성되어야 합니다. 위의 예에서는 특성에 인수가 없으므로 빈 괄호(())를 생략할 수 있습니다.

public class GenericType<T>
{
   [GenericAttribute<T>()] // Not allowed! generic attributes must be fully constructed types.
   public string Method() => default;
}

형식 인수는 typeof 연산자와 동일한 제한을 충족해야 합니다. 메타데이터 주석이 필요한 형식은 허용되지 않습니다. 예를 들어 다음 형식은 형식 매개 변수로 허용되지 않습니다.

  • dynamic
  • string?(또는 nullable 참조 형식)
  • (int X, int Y)(또는 C# 튜플 구문을 사용하는 다른 튜플 형식).

이러한 형식은 메타데이터에서 직접 표시되지 않습니다. 여기에는 형식을 설명하는 주석이 포함됩니다. 모든 경우에 기본 형식을 대신 사용할 수 있습니다.

  • dynamic에 대한 object.
  • string다음을 사용하지 않습니다.string?
  • ValueTuple<int, int>다음을 사용하지 않습니다.(int X, int Y)

제네릭 수학 지원

제네릭 수학 지원을 사용하도록 설정하는 몇 가지 언어 기능이 있습니다.

  • 인터페이스의 static virtual 멤버
  • 확인된 사용자 정의 연산자
  • 완화된 시프트 연산자
  • 부호 없는 오른쪽 시프트 연산자

인터페이스에 static abstract 또는 static virtual 멤버를 추가하여 오버로드 가능한 연산자, 기타 정적 멤버 및 정적 속성을 포함하는 인터페이스를 정의할 수 있습니다. 이 기능의 기본 시나리오는 제네릭 형식에서 수학 연산자를 사용하는 것입니다. 예를 들어, operator +를 구현하는 형식에서 System.IAdditionOperators<TSelf, TOther, TResult> 인터페이스를 구현할 수 있습니다. 다른 인터페이스는 다른 수학 연산 또는 잘 정의된 값을 정의합니다. 인터페이스 문서에서 새로운 구문에 대해 알아볼 수 있습니다. static virtual 메서드를 포함하는 인터페이스는 일반적으로 제네릭 인터페이스입니다. 또한 대부분의 경우 형식 매개 변수가 선언된 인터페이스를 구현한다는 제약 조건을 선언합니다.

자습서 정적 추상 인터페이스 멤버 탐색 또는 .NET 6의 미리 보기 기능 – 일반 수학 블로그 게시물에서 이 기능에 대해 자세히 알아보고 직접 사용해 볼 수 있습니다.

제네릭 수학은 언어에 대한 다른 요구 사항을 만들었습니다.

  • 부호 없는 오른쪽 시프트 연산자: C# 11 이전에는 부호 없는 오른쪽 시프트를 강제하려면 부호 있는 정수 형식을 부호 없는 형식으로 캐스팅하고 시프트를 수행한 다음 결과를 다시 부호 있는 형식으로 캐스팅해야 했습니다. C# 11부터는 부호 없는 시프트 연산자>>>을 사용할 수 있습니다.
  • 완화된 시프트 연산자 요구 사항: C# 11에서는 두 번째 피연산자가 int이거나 암시적으로 int로 변환 가능해야 한다는 요구 사항을 제거합니다. 이러한 변경으로 인해 제네릭 수학 인터페이스를 구현하는 형식을 이러한 위치에서 사용할 수 있습니다.
  • 선택 및 선택 취소된 사용자 정의 연산자: 이제 개발자는 checkedunchecked 산술 연산자를 정의할 수 있습니다. 컴파일러는 현재 컨텍스트를 기반으로 올바른 변형에 대한 호출을 생성합니다. 산술 연산자 문서에서 checked 연산자에 대해 자세히 알아볼 수 있습니다.

숫자 IntPtrUIntPtr

이제 nintnuint 형식은 각각 System.IntPtrSystem.UIntPtr의 별칭을 지정합니다.

문자열 보간의 줄 바꿈

이제 문자열 보간을 위한 {} 문자 안의 텍스트가 여러 줄에 걸쳐 있을 수 있습니다. {} 마커 사이의 텍스트는 C#으로 구문 분석됩니다. 줄 바꿈을 포함한 모든 합법적인 C#은 허용됩니다. 이 기능을 사용하면 패턴 일치 switch 식 또는 LINQ 쿼리와 같이 더 긴 C# 식을 사용하는 문자열 보간을 더 쉽게 읽을 수 있습니다.

언어 참조의 문자열 보간 문서에서 줄 바꿈 기능에 대해 자세히 알아볼 수 있습니다.

목록 패턴

목록 패턴은 목록 또는 배열의 요소 시퀀스를 일치하도록 패턴 일치를 확장합니다. 예를 들어 sequence가 배열 또는 3개의 정수(1, 2, 3)의 목록인 경우 sequence is [1, 2, 3]true입니다. 상수, 형식, 속성, 관계형 패턴을 비롯한 모든 패턴을 사용하여 요소를 일치시킬 수 있습니다. 무시 패턴(_)은 모든 단일 요소와 일치하며 새 범위 패턴(..)은 0개 이상의 요소 시퀀스와 일치합니다.

언어 참조의 패턴 일치 문서에서 목록 패턴에 대한 자세한 내용을 알아볼 수 있습니다.

대리자로의 메서드 그룹 변환 개선

이제 메서드 그룹 변환의 C# 표준에 다음 항목이 포함됩니다.

  • 변환은 이러한 참조가 이미 포함된 기존 대리자 인스턴스를 사용할 수 있도록 허용됩니다(필수는 아님).

이전 버전의 표준에서는 컴파일러가 메서드 그룹 변환을 위해 만든 대리자 개체를 다시 사용할 수 없습니다. C# 11 컴파일러는 메서드 그룹 변환에서 만든 대리자 개체를 캐시하고 해당 단일 대리자 개체를 다시 사용합니다. 이 기능은 Visual Studio 2022 버전 17.2에서 미리 보기 기능으로, .NET 7 Preview 2에서 처음 제공되었습니다.

원시 문자열 리터럴

원시 문자열 리터럴은 문자열 리터럴의 새 형식입니다. 원시 문자열 리터럴은 이스케이프 시퀀스를 요구하지 않고 공백, 새 줄, 포함된 따옴표, 기타 특수 문자를 비롯한 임의의 텍스트를 포함할 수 있습니다. 원시 문자열 리터럴은 세 개 이상의 큰따옴표(""") 문자로 시작합니다. 이는 동일한 수의 큰따옴표로 끝납니다. 일반적으로 원시 문자열 리터럴은 한 줄에 세 개의 큰따옴표를 사용하여 문자열을 시작하고 별도의 줄에 세 개의 큰따옴표를 사용하여 문자열을 종료합니다. 여는 따옴표와 닫는 따옴표 앞의 줄 바꿈은 최종 콘텐츠에 포함되지 않습니다.

string longMessage = """
    This is a long message.
    It has several lines.
        Some are indented
                more than others.
    Some should start at the first column.
    Some have "quoted text" in them.
    """;

닫는 큰따옴표 왼쪽의 공백은 문자열 리터럴에서 제거됩니다. 원시 문자열 리터럴을 문자열 보간과 결합하여 출력 텍스트에 중괄호를 포함할 수 있습니다. 여러 $ 문자는 보간을 시작하고 종료하는 연속 중괄호 수를 나타냅니다.

var location = $$"""
   You are at {{{Longitude}}, {{Latitude}}}
   """;

앞의 예제에서는 두 개의 중괄호가 보간을 시작하고 종료되도록 지정합니다. 세 번째 반복된 여는 중괄호와 닫는 중괄호가 출력 문자열에 포함됩니다.

프로그래밍 가이드의 문자열에 대한 문서의 원시 문자열 리터럴과 문자열 리터럴보간된 문자열에 대한 언어 참조 문서에 대해 자세히 알아볼 수 있습니다.

자동 기본 구조체

C# 11 컴파일러는 생성자 실행의 일부로 struct 형식의 모든 필드가 기본값으로 초기화되도록 보장합니다. 이 변경은 생성자에 의해 초기화되지 않은 모든 필드 또는 자동 속성이 컴파일러에 의해 자동으로 초기화됨을 의미합니다. 생성자가 모든 필드를 명확하게 할당하지 않는 구조체는 이제 컴파일되고 명시적으로 초기화되지 않은 모든 필드는 기본값으로 설정됩니다. 구조체에 대한 문서에서 이 변경 내용이 구조체 초기화에 어떤 영향을 미치는지 자세히 알아볼 수 있습니다.

상수 string에 대한 패턴 일치 Span<char> 또는 ReadOnlySpan<char>

여러 릴리스에 대한 패턴 일치를 사용하여 string에 특정 상수 값이 있는지 테스트할 수 있었습니다. 이제 Span<char> 또는 ReadOnlySpan<char>인 변수와 동일한 패턴 일치 논리를 사용할 수 있습니다.

확장 nameof 범위

이제 해당 메서드의 특성 선언에 있는 nameof 식에 사용될 때 형식 매개 변수 이름과 매개 변수 이름이 범위 내에 있습니다. 이 기능은 nameof 연산자를 사용하여 메서드 또는 매개 변수 선언의 특성에 메서드 매개 변수의 이름을 지정할 수 있음을 의미합니다. 이 기능은 null 허용 분석을 위한 특성을 추가하는 데 가장 유용합니다.

UTF-8 문자열 리터럴

UTF-8 문자 인코딩을 지정하려면 문자열 리터럴에 u8 접미사를 지정할 수 있습니다. 애플리케이션에 HTTP 문자열 상수 또는 유사한 텍스트 프로토콜에 대해 UTF-8 문자열이 필요한 경우 이 기능을 사용하여 UTF-8 문자열 만들기를 간소화할 수 있습니다.

내장 참조 형식에 관한 문서의 문자열 리터럴 섹션에서 UTF-8 문자열 리터럴에 대해 자세히 알아볼 수 있습니다.

필수 멤버

속성과 필드에 required 한정자를 추가하여 생성자와 호출자가 해당 값을 초기화하도록 할 수 있습니다. 생성자가 모든 필수 멤버를 초기화한다는 것을 컴파일러에 알리기 위해 생성자에 System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute를 추가할 수 있습니다.

필수 멤버에 대한 자세한 내용은 속성 문서의 init-only 섹션을 참조하세요.

ref 필드 및 ref scoped 변수

ref struct 내에 ref 필드를 선언할 수 있습니다. 이는 특별한 특성이나 숨겨진 내부 형식이 없는 System.Span<T>와 같은 형식을 지원합니다.

ref 선언에 scoped 한정자를 추가할 수 있습니다. 이는 참조가 이스케이프될 수 있는 범위를 제한합니다.

파일 로컬 형식

C# 11부터 file 액세스 한정자를 사용하여 표시 여부가 선언된 원본 파일로 범위가 지정되는 형식을 만들 수 있습니다. 이 기능은 원본 생성기 작성자가 이름 충돌을 방지하는 데 도움이 됩니다. 언어 참조의 파일 범위 형식에 대한 문서에서 이 기능에 대해 자세히 알아볼 수 있습니다.

참고 항목