C# 10의 새로운 기능

C# 10에는 다음과 같은 기능과 C# 언어 개선 사항이 추가되었습니다.

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

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

레코드 구조체

record struct 또는 readonly record struct 선언을 사용해 값 형식 레코드를 선언할 수 있습니다. 이제 recordrecord class 선언이 있는 참조 형식임을 명시할 수 있습니다.

구조체 형식 개선

C# 10에서는 다음과 같은 구조체 형식 관련 개선이 도입되었습니다.

  • 구조체 형식에서 매개 변수가 없는 인스턴스 생성자를 선언하고 해당 선언에서 인스턴스 필드 또는 속성을 초기화할 수 있습니다. 자세한 내용은 구조체 형식 문서의 구조체 초기화 및 기본값 섹션을 참조하세요.
  • with의 왼쪽 피연산자는 구조체 형식 또는 무명(참조) 형식일 수 있습니다.

보간된 문자열 처리기

보간된 문자열 식에서 결과 문자열을 빌드하는 형식을 만들 수 있습니다. .NET 라이브러리는 많은 API에서 이 기능을 사용합니다. 이 자습서에 따라 빌드할 수 있습니다.

전역 using 지시문

지시문이 컴파일의 모든 소스 파일에 적용되도록 컴파일러에 지시하려면 using 지시문global 한정자를 추가할 수 있습니다. 이는 일반적으로 프로젝트의 모든 소스 파일입니다.

파일 범위 네임스페이스 선언

모든 후속 선언이 선언된 네임스페이스의 멤버임을 선언하려면 새로운 형식의 namespace 선언을 사용할 수 있습니다.

namespace MyNamespace;

이 새 구문을 사용하면 namespace 선언에서 가로와 세로 공간이 모두 절약됩니다.

확장 속성 패턴

C# 10부터 속성 패턴 내에서 중첩된 속성 또는 필드를 참조할 수 있습니다. 예를 들어 다음의 형식 패턴은

{ Prop1.Prop2: pattern }

C# 10 이상에서 유효하며 다음과 동일합니다.

{ Prop1: { Prop2: pattern } }

C# 8.0 이상

자세한 내용은 확장 속성 패턴 기능 제안 노트를 참조하세요. 속성 패턴에 대한 자세한 내용은 패턴 문서의 속성 패턴 섹션을 참조하세요.

람다 식 개선

C# 10에서는 람다 식이 처리되는 방식에 몇 가지 개선이 적용되었습니다.

  • 람다 식이 컴파일러가 람다 식 또는 메서드 그룹으로부터 대리자 형식을 유추할 수 있는 자연 형식을 가질 수 있습니다.
  • 컴파일러가 반환 형식을 유추할 수 없는 경우 람다 식이 반환 형식을 선언할 수 있습니다.
  • 람다 식에 특성을 적용할 수 있습니다.

이러한 기능은 람다 식을 메서드 및 로컬 함수와 더 비슷하게 만들어 줍니다. 대리자 형식의 변수를 선언하지 않고도 람다 식을 더 쉽게 사용할 수 있으며 새로운 ASP.NET Core 최소 API와 더 원활하게 작동합니다.

보간된 상수 문자열

C# 10에서는 모든 자리 표시자가 그 자체로 상수 문자열인 경우 문자열 보간을 사용하여 const 문자열을 초기화할 수 있습니다. 문자열 보간을 사용하면 애플리케이션에서 사용되는 상수 문자열을 작성할 때 보다 읽기 쉬운 상수 문자열을 만들 수 있습니다. 해당 상수는 런타임에 문자열로 변환되기 때문에 자리 표시자 식은 숫자 상수일 수 없습니다. 현재 문화권이 해당 문자열 표현에 영향을 줄 수 있습니다. const에 대한 언어 참조에서 자세히 알아보세요.

레코드 형식은 ToString을 봉인할 수 있음

C# 10에서는 레코드 형식에서 ToString을 재정의할 때 sealed 한정자를 추가할 수 있습니다. ToString 메서드를 봉인하면 컴파일러가 파생된 레코드 형식에 대해 ToString 메서드를 합성할 수 없습니다. A sealedToString 는 모든 파생 레코드 형식이 공통 기본 레코드 형식에 정의된 메서드를 사용하도록 ToString 합니다. 레코드에 대한 문서에서 이 기능에 대해 자세히 알아볼 수 있습니다.

동일한 분해의 할당 및 선언

이 변경을 통해 이전 버전 C#의 제한이 제거됩니다. 이전에는 분해에서 모든 값을 기존 변수에 할당하거나 새로 선언된 변수를 초기화할 수 있었습니다.

// Initialization:
(int x, int y) = point;

// assignment:
int x1 = 0;
int y1 = 0;
(x1, y1) = point;

C# 10에서는 이 제한이 제거됩니다.

int x = 0;
(x, int y) = point;

한정된 할당 개선

C# 10 이전에는 한정된 할당과 null 상태 분석이 가양성인 경고를 생성하는 시나리오가 많았습니다. 대표적인 시나리오로 부울 상수와 비교하는 경우, if 문에서 true 또는 false 문에만 있는 변수에 액세스하는 경우, null 병합 식을 들 수 있습니다. 이러한 시나리오는 이전 버전의 C#에서는 경고를 생성했지만 C# 10에서는 경고를 생성하지 않습니다.

string representation = "N/A";
if ((c != null && c.GetDependentValue(out object obj)) == true)
{
   representation = obj.ToString(); // undesired error
}

// Or, using ?.
if (c?.GetDependentValue(out object obj) == true)
{
   representation = obj.ToString(); // undesired error
}

// Or, using ??
if (c?.GetDependentValue(out object obj) ?? false)
{
   representation = obj.ToString(); // undesired error
}

이 개선으로 인해 한정된 할당 및 null 상태 분석에 대한 경고가 더 정확해졌습니다.

메서드의 AsyncMethodBuilder 특성 허용

C# 10 이상에서는 지정된 작업과 유사한 형식을 반환하는 모든 메서드에 대해 메서드 작성기 형식을 지정하는 것에 더해, 단일 메서드에 대해 여러 비동기 메서드 작성기를 지정할 수 있습니다. 사용자 지정 비동기 메서드 작성기를 이용하면, 지정된 메서드가 사용자 지정 작성기를 활용할 수 있는 고급 성능 조정 시나리오를 사용할 수 있습니다.

자세한 내용은 컴파일러에서 읽은 특성에 대한 문서에서 AsyncMethodBuilder에 대한 섹션을 참조하세요.

CallerArgumentExpression 특성 진단

System.Runtime.CompilerServices.CallerArgumentExpressionAttribute를 사용하여, 컴파일러가 다른 인수의 텍스트 표현으로 바꿀 매개 변수를 지정할 수 있습니다. 이 기능은 라이브러리가 보다 구체적인 진단을 만들 수 있도록 지원합니다. 다음 코드는 조건을 테스트합니다. 조건이 false이면 예외 메시지가 condition으로 전달된 인수의 텍스트 표현을 포함합니다.

public static void Validate(bool condition, [CallerArgumentExpression("condition")] string? message=null)
{
    if (!condition)
    {
        throw new InvalidOperationException($"Argument failed validation: <{message}>");
    }
}

이 기능은 언어 참조 섹션의 호출자 정보 특성에 관한 문서에서 자세히 알아볼 수 있습니다.

향상된 #line pragma

C# 10은 #line pragma에 대한 새 형식을 지원합니다. 새 형식을 직접 사용할 일은 없겠지만, 그 영향은 확인할 수 있습니다. 이로 인해 Razor와 같은 DSL(Domain-Specific Language)에서 더욱 정교한 출력을 얻을 수 있습니다. Razor 엔진은 이러한 개선 사항을 사용하여 디버깅 경험을 향상합니다. 디버거가 Razor 소스를 보다 정확하게 강조 표시하는 것을 볼 수 있습니다. 새로운 구문에 대해 자세히 알아보려면 언어 참조의 전처리기 지시문에 관한 문서를 참조하세요. Razor 기반 예제는 기능 사양을 참조하세요.