.NET 11 Preview 3: 개발자 리뷰
.NET 11은 2026년 11월 GA가 계획된 시점에서 약 6개월 정도 세 번째 미리 보기에 도달하며, 대부분의 배관이었던 Preview 1 및 2와 달리 Preview 3은 출시 형태를 실제로 느낄 수 있는 것입니다.
Runtime Async는 "미리 보기 기능 게이트" 실험을 중단하고, JIT는 또 다른 무료 최적화 패키지, ASP.NET Core는 기본적으로 Zstandard를 지원하며, C# 15의 유니온 타입은 사람들이 수년 동안 묻던 언어 기능입니다.
이것은 LTS 릴리스가 아닙니다. .NET 11은 24개월 동안 지원되는 다음 표준 기간 지원 버전이며, 이는 이미 업그레이드 여부에 대한 계산을 변화시킵니다. 아래는 개발자로서 주목할 만한 점과 여전히 거친 부분이 있는 곳입니다.
C# 15 유니온 타입: 대형 기능
만약 당신이 OneOf<T1, T2> 라이브러리를 작성하고, 봉인된 레코드 계층 구조를 직접 만들고 있거나 F# 개발자를 부러워하고 있었다면, 이것은 헤드라인입니다. C# 15는 고정된 유형 집합 중 정확히 하나의 값을 선언하는 결합 키워드를 도입하며, 이는 컴파일러에 의해 철저히 검사됩니다. 유니온 타입은 Preview 2에서 도착했습니다; Preview 3는 이에 대한 IDE 지원을 개선합니다.
C# 팀의 접근 방식은 F# 차별 유니온보다 타입 유니온에 더 가깝습니다: 멤버 타입은 유니온 선언 내부에 중첩되어 있지 않은 별도의 기존 타입입니다. 유니온은 본질적으로 객체를 감싸고 그것에 들어갈 수 있는 것을 제한하는 구조체입니다. 호출 사이트에서 이는 마치 네이티브처럼 느껴집니다 - 멤버 유형에서 결합으로의 암시적 변환, Pet.Value에 대한 모든 경우를 다루는 switch 표현식, 그리고 컴파일러가 모든 경우를 볼 수 있을 때 기본 팔이 필요 없습니다.
[Union]
public partial struct Pet : IUnion
{
public Pet(Dog dog);
public Pet(Cat cat);
public Pet(Bird bird);
}
string Describe(Pet pet) => pet.Value switch
{
Dog d => $"Dog named {d.Name}",
Cat c => $"Cat ({c.Color})",
Bird b => $"Bird, {b.Species}",
// no default - compiler knows the set is closed
};
[Union]
public partial struct Pet : IUnion
{
public Pet(Dog dog);
public Pet(Cat cat);
public Pet(Bird bird);
}
string Describe(Pet pet) => pet.Value switch
{
Dog d => $"Dog named {d.Name}",
Cat c => $"Cat ({c.Color})",
Bird b => $"Bird, {b.Species}",
// no default - compiler knows the set is closed
};
<Union>
Public Partial Structure Pet
Implements IUnion
Public Sub New(dog As Dog)
End Sub
Public Sub New(cat As Cat)
End Sub
Public Sub New(bird As Bird)
End Sub
End Structure
Function Describe(pet As Pet) As String
Return pet.Value Select Case
Case d As Dog
Return $"Dog named {d.Name}"
Case c As Cat
Return $"Cat ({c.Color})"
Case b As Bird
Return $"Bird, {b.Species}"
' no default - compiler knows the set is closed
End Select
End Function장점은 명백합니다: 닫힌 유형, 잘못된 상태 없음, 3am이 아닌 컴파일 시간에 철저함. 유니온에 상어를 추가하면 Pet에 대한 모든 switch가 경고와 함께 표시됩니다.
단점도 현실적이며, 어떤 솔직한 리뷰에서든 표시할 가치가 있습니다. 노출된 객체 값 속성은 냄새입니다 - 이것을 타입-안전한 무언가 뒤에 숨기는 것에 대한 GitHub 공개 토론이 있습니다. 공개 생성자는 유니온이 허용하는 타입을 암시적으로 정의하며, 이는 발견 할 수 없고, 명시적이지 않습니다. F# 상호 운용은 해결되지 않았습니다 (두 모델은 근본적으로 다릅니다). 더 넓은 철저한 이야기에는 여전히 사각지대가 있습니다: 폐쇄된 계층 및 폐쇄된 열거형은 그림을 완성할 수 있는 두 가지 제안이며, 여전히 제안 상태에 머물러 있습니다. 유니온만으로도 훌륭합니다. 유니온과 닫힌 열거형 및 닫힌 계층이 함께하면 세대의 변화를 가져올 것입니다. 아직 거기에 도달하지 않았습니다.
Runtime Async V2 및 JIT 개선 사항
Runtime Async는 비동기/대기의 실제 실행 방식을 완전히 새로 썼습니다. C# 컴파일러가 비동기 메서드당 상태 기계 클래스를 생성하는 대신, 런타임 자체가 중단 및 재개를 관리합니다. 눈에 띄는 결과: 더 깔끔한 스택 추적, 더 작은 할당 및 디버거가 MoveNext 프레임을 넘어 자체 코드를 찾을 필요가 없습니다.
사전 보기 3에서 Runtime Async는 EnablePreviewFeatures 요구 사항을 제거합니다. 여전히 기능 스위치를 전환해야 합니다 - <Features>runtime-async=on</Features> - 하지만 더 이상 모든 API 호출을 미리 보기 영역으로 선택할 필요는 없습니다. NativeAOT 및 ReadyToRun 지원도 이번 미리 보기에서 도착하여 JIT 및 AOT 시나리오 간의 간격을 좁혔습니다. 연속 객체는 더 공격적으로 재사용되며, 변경되지 않은 로컬은 중단을 통해 저장되지 않습니다. 비동기 중심 코드 경로 - 예를 들어 Kestrel 파이프라인 또는 EF Core 쿼리 작업자 - 에서 이는 할당 압력의 의미 있는 감소입니다.
JIT는 "기존 코드를 더 빠르게"로 또 다른 꾸러미를 가져옵니다:
- 다중 대상을 가진 switch 표현식, 예를 들어 x는 0 또는 1 또는 2 또는 3 또는 4였고, 이제 가지 없는 확인으로 접힙니다.
- 값[^1] + 값[^2] 패턴의 범위 검사는 더 공격적으로 제거되며, 루프에서 일반적인 i + cns < len 케이스가 깔끔하게 수렴됩니다.
- 부호 없는 정수에서 부동 소수점 및 부호 없는 정수에서 이중으로의 캐스트는 pre-AVX-512 x86 하드웨어에서 더 빠릅니다 - 니치하지만, 오래된 시스템에서는 중요합니다.
WebAssembly 사용자들은 런타임에서 직접 WebCIL 페이로드 로딩을 얻고, 더 나은 디버그 심볼, 그리고 왕복 오버헤드 없이 float[] / Span<float> / ArraySegment<float> 마샬링을 사용할 수 있습니다. 이 중 하나도 개별적으로는 극적인 일이 아니지만 함께하면 Blazor WASM이 타협처럼 느껴지지 않게 만드는 누적 작업입니다.
갈고리 잡는 것은 하드웨어 기준선입니다. .NET 11은 x86/x64 및 Arm64의 최소 명령어 세트를 높였습니다. Apple Silicon과 대부분의 Linux SBC는 괜찮지만, Arm64의 ReadToRun 타겟은 LSE만 추가하지만 매우 오래된 x86 하드웨어는 제외되었습니다. 배포를 하기 전에 더빙이 가능하다는 것을 가정하지 마시고, 함대를 감사하세요.
ASP.NET Core 및 Blazor
Zstandard이 여기서 주요 뉴스입니다. ASP.NET Core는 이제 응답 압축과 요청 디컴프레션을 위한 zstd를 지원하며, 미들웨어를 추가할 때 기본적으로 활성화되어 있습니다. 구성은 예상대로의 형태입니다:
builder.Services.AddResponseCompression();
builder.Services.AddRequestDecompression();
builder.Services.Configure<ZstandardCompressionProviderOptions>(options =>
{
options.CompressionOptions = new ZstandardCompressionOptions { Quality = 6 };
});
builder.Services.AddResponseCompression();
builder.Services.AddRequestDecompression();
builder.Services.Configure<ZstandardCompressionProviderOptions>(options =>
{
options.CompressionOptions = new ZstandardCompressionOptions { Quality = 6 };
});
Imports Microsoft.Extensions.DependencyInjection
builder.Services.AddResponseCompression()
builder.Services.AddRequestDecompression()
builder.Services.Configure(Of ZstandardCompressionProviderOptions)(Sub(options)
options.CompressionOptions = New ZstandardCompressionOptions With {.Quality = 6}
End Sub)JSON이나 텍스트 페이로드를 이미 zstd를 사용하는 클라이언트에게 제공하는 API에 대해, 이는 서드파티 라이브러리에 대한 종속성 없이 측정 가능한 대역폭 이점입니다. 또한 이것은 Microsoft 내부에서가 아니라 커뮤니티의 기여로 이루어진 점이 눈에 띕니다, 이는 건강한 신호입니다.
Blazor의 Virtualize<TItem>가 마침내 모든 행이 동일한 높이라고 가정하는 것을 멈춥니다. 이는 오랫동안 지속된 짜증이었습니다: 변수 내용이 있는 모든 리스트 - 댓글, 채팅 메시지, 줄넘긴 텍스트가 있는 모든 것 - 이 수동으로 해결해야 했습니다. 이제 컴포넌트는 런타임에 항목을 측정합니다. 사전 보기 3 릴리스는 Blazor 버그를 다수 수정하기도 합니다: Virtualize에서의 널 참조, overflow-x로 스크롤-컨테이너 감지, 게시된 WASM 앱에서의 웹 워커 템플릿, TempData 지연 로딩 경계 사례, 그리고 ResourceCollectionProvider에서의 IJSObjectReference 누출. 개별적으로는 작지만 집합적으로 이 프레임워크가 "매 릴리스마다 새로운 것" 단계를 지나 성숙해지는 신호입니다.
Kestrel은 또한 새로운 연결의 첫 요청 지연을 줄이기 위해 제어 스트림 및 설정 프레임을 기다리지 않고 HTTP/3 요청을 처리하기 시작합니다. HTTP/3 P99를 측정하고 이상한 콜드 스타트 꼬리를 보고 있었다면, 이것이 당신을 위한 해결책입니다.
.NET MAUI
Preview 3의 MAUI는 너무 오랫동안 베타처럼 느껴졌던 간격을 메우는 데 주로 초점을 맞춥니다. 제어가 핀 클러스터링, 사용자 정의 핀 아이콘, 사용자 정의 JSON 스타일링, 그리고 원, 다각형, 폴리라인에서의 클릭 이벤트를 얻습니다 - 이는 실제 제작 지도 UI에 필요한 모든 것들이며, 이전에는 플랫폼별로 사용자 정의 핸들러가 필요했습니다. Map. 이제 사용자 정의 없이 내장된 LongPressGestureRecognizer가 사용 가능합니다. 묵시적 XAML 네임스페이스 선언이 기본적으로 켜져, 모든 파일의 상단에 보일러플레이트를 줄입니다.
플랫폼 동등성이 상승했습니다: Permissions.PostNotifications는 이제 iOS에 구현되었으며 (이전에는 Android 전용이었음), Android는 Android 17 및 API 레벨 37에 대한 미리보기 지원을 얻었습니다.
정직한 평가: 이는 안정적이고, 합리적인 반복이며, 재발명이 아닙니다. 2026년의 MAUI는 2023년의 MAUI보다 훨씬 더 나은 상태에 있지만, 이전에 이를 떠났다면, Preview 3만으로는 돌아오지 않을 것입니다. 이미 MAUI를 사용 중이라면, 이것이 당신이 원하는 정확한 삶의 질 개선 사항입니다.
SDK, CLI 및 .NET 감시
여기에서 작은 것들이 합쳐지는 섹션입니다. 매일의 작업 흐름을 실제로 변화시킨다고 생각하는 몇 가지:
.NET sln은 이제 CLI에서 직접 솔루션 필터(.slnf)를 생성하고 편집할 수 있습니다. 모노레포 및 대형 Microsoft 스타일 솔루션에 대해, 200개 프로젝트의 SLN을 열어 그 중 세 개를 작업하는 것은 실제로 비용이 많이 들었습니다. 이제 터미널에서 범위를 지정할 수 있습니다:
dotnet new slnf --name MyApp.slnf
dotnet sln MyApp.slnf add src/Lib/Lib.csprojdotnet new slnf --name MyApp.slnf
dotnet sln MyApp.slnf add src/Lib/Lib.csproj파일 기반 앱 (.NET run app.cs 워크플로우)은 드디어 #:include를 지원하여 C# 스크립트가 별도의 파일로 도우미를 나눌 수 있습니다. 이를 Roslyn의 지시문 에디터 완성과 결합하면, 파일 기반 앱이 "장난감"에서 "실제 자동화 도구에 적합"한 것으로 바뀌며, PowerShell 및 작은 Python 스크립트가 오랫동안 차지했던 틈새시장을 지니게 됩니다.
.NET run -e FOO=BAR는 셸 상태를 내보내거나 시작 프로파일을 편집하지 않고, 명령줄에서 환경 변수를 전달할 수 있도록 합니다. 사소하지만, 세 개의 터미널을 다른 ASPNETCORE_ENVIRONMENT 값으로 열어본 적이 있다면 그 고통을 알고 있을 것입니다.
.NET watch는 Aspire 앱 호스트와 통합되어 파일 변경 후 충돌 시 자동으로 다시 시작되며, WinForms 및 WPF에 대해 Ctrl+C를 더 매끄럽게 처리합니다(영구적 종이 상처). .NET format은 다중 타겟 프로젝트에 대해 --framework를 허용합니다. MTP 모드의 .NET test는 --artifacts-path를 지원합니다. .NET tool exec / dnx는 이제 추가 승인을 묻지 않으며, 이는 일회성 도구 실행에 있어 마찰점이었습니다.
문제점
균형 잡힌 리뷰는 거친 부분을 포함하며, Preview 3에는 이런 부분이 존재합니다.
도구 스토리는 거칠게 진행중입니다. .NET 10가 배송된 지 6개월 후 Visual Studio 2026이 여전히 미리 보기이며, Microsoft 호스팅 빌드 에이전트에도 안정적인 VS 2026 지원이 아직 없습니다. .NET 10 SDK 패치 릴리스의 변경 사항은 MSBuild 18(VS 2026)을 요구하며, 이는 Microsoft가 홍보하는 semver 보장을 깨끗하게 위반한 것입니다. Microsoft 호스트 에이전트에서 CI를 실행하는 누구든지 SDK 10.0.4를 고정했거나 미리 보기 빌드 이미지로 전환해야 했습니다. .NET 11 미리 보기로 CI 파이프라인을 이동하려고 한다면, 팀의 자백에 의해 미리 보기 SDK가 10.0.2 및 10.0.3에서 안정화되기 전에 문제를 발생시켰습니다.
Runtime Async는 여전히 선택 사항입니다. 사전 보기 기능 게이트가 사라져도, 여전히 runtime-async=on를 전환해야 합니다. 초록불 코드에는 괜찮습니다; NuGet에 수출된 라이브러리의 경우 소비자가 스위치를 켜지 않았다고 가정 할 수 없으므로, 기능이 기본값으로 켜질 때까지 (즉, .NET 11에서는 아님) 실제적인 이점이 지연됩니다.
하드웨어 요구 사항 상승. 최소 x86/x64 명령어 세트 요구 사항이 올라갔습니다. 대부분의 팀은 이를 눈치 채지 못할 것입니다. 일부는 그것에 영향 받을 것이며, 사전 감사하지 않으면 배포 시 이를 알고 빼낼 것입니다.
STS, LTS가 아님. .NET 11은 24개월 동안 지원됩니다. .NET 10은 현재의 LTS이며, 36개월간 지원됩니다. 느린 업그레이드 주기를 가지고 있는 상점에서는 .NET 10이 여전히 더 보수적인 선택이며, .NET 11 사용은 2028년에 또 다른 업그레이드를 약속하는 것을 의미합니다. STS 채택의 이유는 기능입니다; 캘린더는 반대 이유입니다.
미리 보기는 미리 보기입니다. 이것은 안정성에 대한 불평이 아닙니다 - Microsoft의 미리 보기 프로세스는 좋았습니다 - 그러나 Preview 3는 릴리즈 후보가 아닙니다. 프로덕션 배포는 최소한 RC1을 기다립니다. 내부 도구, 사이드 프로젝트 및 탐험은 현재의 적절한 범위입니다.
평가
매일 C#을 작성한다면, .NET 11 Preview 3는 이번 주에 설치하고 사용해 볼 가치가 있습니다 - 특히 수년간의 가장 중요한 언어 변경 사항인 유니온 타입을 다루기 위해. 라이브러리를 유지 관리하는 경우, JIT 및 Runtime Async 작업 덕분에 .NET 11에서 수정 없이 코드를 더 빠르게 할 수 있으며, 이는 최고의 업그레이드 유형입니다. MAUI 앱을 출시하는 경우, 지도 및 동작 작업은 실제로 발전입니다.
프로덕션 .NET 작업 부하를 실행하는 경우, 대답은 지루하지만 계획을 계속하고, 계속 관찰하며, 11월에 GA를 즐겨 찾기에 추가하는 것입니다. 흥미를 끄는 부분들은 도착하고 있지만, 도구 체인 - VS, 빌드 에이전트 및 SDK 패치 주기 - 은 실제 마찰이 있는 곳이며, 아직 해결되지 않았습니다.
| --- |
출처: .NET 블로그 발표, .NET 11의 새로운 점 (Microsoft Learn), 런타임 릴리스 노트, ASP.NET Core 릴리스 노트, SDK 릴리스 노트, C# 15의 유니온 타입 탐색.
