一如 .NET Core 開始的 Roadmap 規劃,.NET 固定於每年 11 月發佈新版,單數版號為 STS、雙數為 LTS (長期支援版,提供三年支援),.NET 11 於 2026-11-10 在 .NET Conf 2026 正式發佈,搭配 C# 15、F# 11、EF Core 11。

AI 時代,為程式語言新版寫筆記顯得有點尷尬,套句好口貝雪瑞的名言「零人在乎」,哈!

不過,考慮在企業裡 .NET 能再戰十年沒問題,多懂一點 C# 讓你在 AI 裁員潮下提高一些存活機率,或許可當成動機。XD

本次發行的 .NET 11 屬 STS (Standard Term Support) 版本,支援期兩年;而 .NET 10 仍是 LTS,.NET 8 與 .NET 9 則於 2026-11-10 終止支援。

先介紹 C# 15 的新功能。其中 Memory safety 為預覽性質,需加註 <LangVersion>preview</LangVersion>,其餘皆為正式功能。

  1. Union types
    可使用 union 關鍵字宣告「值必為數種型別之一」,各 case 型別可隱含轉換;switch 運算式由編譯器檢查是否涵蓋所有 case,不需 default 分支。
    public record class Cat(string Name);
    public record class Dog(string Name);
    public record class Bird(string Name);
    
    public union Pet(Cat, Dog, Bird);
    
    Pet pet = new Dog("Rex");
    string name = pet switch
    {
        Dog d => d.Name,
        Cat c => c.Name,
        Bird b => b.Name,
    };
    
  2. Closed hierarchies
    closed 修飾詞限制類別只能在宣告的組件內被繼承,編譯器掌握所有直接子型別,可進行完整性檢查。
    closed 類別隱含 abstract,不可與 sealed、static、明確的 abstract 併用,且不具遞移性,中間層子類別要再標 closed 才會往下檢查。
    // === Gates.dll(宣告 closed 的組件)===
    public closed record class GateState;
    public record class Closed : GateState;
    public record class Open(float Percent) : GateState;
    
    // === App.exe(參考 Gates.dll 的其他組件)===
    public record class HalfOpen : GateState;   // 編譯錯誤:不能在宣告組件以外繼承 closed 類別
    
    // 外部不能新增子型別,編譯器可確認以下 switch 已涵蓋所有情況
    string Describe(GateState state) => state switch
    {
        Closed => "closed",
        Open(var percent) => $"{percent}% open",
    };
    
  3. Collection expression arguments
    集合運算式第一個元素可寫 with(...),將引數傳給建構式或 Factory 方法 (例如集合型別、Comparer)。
    string[] values = ["one", "two", "three"];
    
    // C# 14 以前:要傳建構式引數,就不能用集合運算式
    var names = new List<string>(capacity: values.Length * 2);
    names.AddRange(values);
    
    var set = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Hello", "HELLO" };
    
    // C# 15:with(...) 的內容就是建構式引數
    List<string> names2 = [with(capacity: values.Length * 2), .. values];
    HashSet<string> set2 = [with(StringComparer.OrdinalIgnoreCase), "Hello", "HELLO"];
    
  4. Extension indexers
    extension 區塊內可宣告索引子,需有具名的 receiver 參數。
    // C# 14:extension 區塊內只能用方法代替索引子
    public static class SequenceExtensions
    {
        extension(IEnumerable<int> sequence)
        {
            public int At(int index) => sequence.ElementAt(index);
        }
    }
    
    int third = Enumerable.Range(1, 10).At(2);   // 3
    
    // C# 15:extension 區塊內可宣告索引子
    public static class SequenceIndexer
    {
        extension(IEnumerable<int> sequence)
        {
            public int this[int index] => sequence.ElementAt(index);
        }
    }
    
    int third2 = Enumerable.Range(1, 10)[2];     // 3
    
  5. Labeled break / continue
    break、continue 可指定外層迴圈或 switch 的標籤,免除旗標變數或 goto。
    outer: for (int row = 0; row < grid.Height; row++)
    {
        for (int col = 0; col < grid.Width; col++)
        {
            // 指定 continue 或 break 更外層的迴圈
            if (grid[row, col].IsBlocked) continue outer;
            if (grid[row, col].IsGoal) break outer;
        }
    }
    
  6. Memory safety (Preview)
    unsafe 的意義從「這裡有指標」改為「實際存取 Unmanaged 記憶體的操作」。(需 <LangVersion>preview</LangVersion>,新規則另需 updated-memory-safety-rules 功能旗標。)
    宣告指標型別、&、fixed、stackalloc 轉指標、sizeof 不再需要 unsafe。
    指標取值 (*p、p->m、p[i]) 與函式指標呼叫仍需 unsafe。
    新增 unsafe(expression) 運算式寫法。
  7. 其他
    • 介面的非 virtual 靜態成員,可在不支援 Default Interface Implementation 的舊 Runtime 上宣告與呼叫。

.NET Runtime 部分,有一些調整與強化,但提高了最低硬體需求:

  • x86/x64:JIT/AOT 基準由 x86-64-v1 升為 x86-64-v2 (需 SSE4.2、POPCNT 等);Windows / Linux 的 ReadyToRun 目標升為 x86-64-v3 (AVX2 等)。(x86-64-v* 是 AMD、Intel、Red Hat、SUSE 共同在原始 x86-64 基準之上定義的微架構等級)
  • Arm64:Windows 需 LSE (Large System Extensions);Linux 最低需求不變 (Raspberry Pi 仍可用);Apple 不變。

不符基準的 CPU 會無法執行,並可能顯示缺少 baseline instruction sets 的訊息。

另外,.NET 11 的 async 的暫停 / 恢復可改由 Runtime 處理:Stack Trace 更乾淨、負擔更低。此為 Preview 功能,但 net11.0 專案不需 EnablePreviewFeatures,加下列設定即可啟用;Runtime 程式庫本身已用此模式編譯。 xml <PropertyGroup> <Features>runtime-async=on</Features> </PropertyGroup>

還有一些看不見的底層強化:

  • JIT:減少多餘的邊界檢查與分支、強化 Devirtualization、常數摺疊 (含 SequenceEqual)。
  • Native AOT:共用介面分派 Helper,提升大量使用介面的程式效能。
  • 硬體指令:Half 使用 FP16 指令、Arm SVE2、AVX-VNNI-512,以及 Vector128<T> 等新增 Zip、Unzip、Concat、CreateGeometricSequence。
  • In-process crash report (Managed Stack Trace 與 Runtime 狀態) 擴及 Linux 與 macOS。

至於程式庫 (BCL) 有一些小改良,我看到的亮點是 Process.RunAndCaptureText,這功能超實用,以前得自己寫,現在內建了。其餘有些偏冷僻,可能沒啥機會用到。

  • Process:新增一次完成「執行並擷取輸出」的 RunAndCaptureText (大推) 以及 ProcessStartInfo.StartSuspended、Process.Signal(PosixSignal)、Process.TryGetProcessById、ProcessExitStatus。
    // 同步版,可指定逾時
    ProcessTextOutput result = Process.RunAndCaptureText(
        "dotnet", ["--info"], timeout: TimeSpan.FromSeconds(30));
    
    Console.WriteLine(result.StandardOutput);
    Console.WriteLine(result.StandardError);
    Console.WriteLine(result.ExitStatus.ExitCode);
    
    // 非同步版,以 CancellationToken 控制
    ProcessTextOutput r2 = await Process.RunAndCaptureTextAsync("git", ["status"], ct);
    
  • 壓縮:System.IO.Compression 內建 Zstandard;讀取 ZIP 會驗證 CRC32 (行為變更);Base64 API 擴充。
  • Stream:ReadOnlyMemoryStream、WritableMemoryStream、ReadOnlySequenceStream、StringStream,包裝記憶體資料免複製。
  • System.Text.Json:支援 C# union 與 F# discriminated union、JSON Lines (JSONL) 輸出、多型與 Source Generation 擴充。
  • LINQ:FullJoin (保留兩側未配對元素),以及回傳 Tuple 的 Join / GroupJoin 多載。
  • 數值:Decimal32、Decimal64、Decimal128、泛型 Complex<T>、Random.NextInteger<T>。
  • 驗證:AsyncValidationAttribute、IAsyncValidatableObject、Validator.ValidateObjectAsync;Options 非同步驗證 IAsyncStartupValidator。
  • 網路:DnsResolver 支援具型別的 DNS 記錄查詢、HTTP Request Body 壓縮、QuicStream.Priority、SocketsHttpHandler.InitialHttp2MaxConcurrentStreams。
  • 加密:X25519DiffieHellman、Aes.EncryptKeyWrap / DecryptKeyWrap;複合 ML-KEM 與 HPKE (Experimental)。
  • 集合:EqualityComparer<T>.Create (Key Selector)、BitArray 可由 Span 建構。
  • 診斷:MemoryCache 內建 OpenTelemetry Metrics;Microsoft.Extensions.Diagnostics 可宣告式設定 Activity 追蹤規則。
  • 其他:CBOR 增量讀取、Tar 格式選擇、Console 支援 FORCE_COLOR。

SDK 與 CLI 有一些小加強:

  • CLI 啟動加速:預設啟用 Native AOT CLI Host 與常駐 MSBuild Server。
  • Linux / macOS 安裝檔縮小 (組件去重複)。
  • File-based apps:#:include 可跨多個原始檔,另支援直接參考 DLL、dotnet format。
  • dotnet run -e 傳入環境變數;dotnet sln 可建立、編輯 Solution Filter (.slnf)。
  • dotnet watch:整合 Aspire AppHost、當機自動恢復、行動裝置選擇。
  • dotnet test (Microsoft.Testing.Platform):--timeout、--maximum-failed-tests、--results-directory-layout per-module;選項與 VSTest 不互通。
  • 容器發佈:SOURCE_DATE_EPOCH 產生可重現的 Image Digest、Podman 多架構建置。
  • NuGet:可設定套件最短發佈時間 (--min-publish-age-hours),延後採用剛發佈的版本。
  • CLI 遙測由 Application Insights 改為 OpenTelemetry。

最後是 ASP.NET Core。

  • Minimal APIs
    JSON Request / Response Body 支援 C# union,OpenAPI 以 anyOf 表示;不支援 Route、Query、Header、Form 繫結。
    新增 [ShortCircuit] 屬性可在路由後略過其餘 Middleware。而 Endpoint Filter 改為在參數繫結失敗時也會執行,可改寫 400 回應。
    public union UnionIntString(int, string);
    app.MapGet("/value", () => new UnionIntString(42));
    app.MapGet("/health", [ShortCircuit] () => "Healthy");
    
  • 提供非同步驗證 (AsyncValidationAttribute、IAsyncValidatableObject),Minimal APIs 與 Blazor 表單皆適用;內建訊息多語系。
  • OpenAPI:預設改產生 3.2 版本但可指定回 3.1;支援 SSE 事件 Schema、HTTP QUERY 方法、二進位檔案回應;[Obsolete] 對應 deprecated: true。
  • SignalR:連線不需重連即可更新驗證資訊 (EnableAuthenticationRefresh);取消 InvokeAsync 的 CancellationToken 可取消一般 Hub 方法。
  • 驗證授權:Identity 改用 TimeProvider;Passkey 顯示名稱自動推斷;Device Bound Session Credentials (Experimental)。
  • 觀測:HTTP Server Activity 內建 OpenTelemetry 語意屬性,.AddSource("Microsoft.AspNetCore") 即可收集。
  • 其他:IOutputCachePolicyProvider、WSL 開發憑證自動信任、Microsoft.AspNetCore.Grpc.Swagger 標為 Deprecated。

【ASP.NET Core 升級注意事項】

  • OpenAPI 預設 3.2,且 Microsoft.OpenApi 升級至 3.3.1,需確認 Client 產生器與 API Gateway 相容。
  • QuickGrid 欄位標題與分頁由 <button> 改為 <a>,CSS Selector 需調整;同頁多個 Grid 需設不同 QueryParameterNameOptions。
  • Virtualize.OverscanCount 預設值由 3 改為 15。
  • Blazor Web App 範本不再呼叫 app.UseAntiforgery(),CSRF 保護自動處理。

Blazor、桌面與行動裝置 App 也有一些更新,目前我沒用到,先跳過。

EF Core 11 部分的改良包含:

  • 查詢:移除更多不必要的 JOIN、改善 GroupBy 轉譯、支援 FullJoin (視 Provider)。
  • Complex Type 與 JSON 欄位可搭配 TPT / TPC 繼承。
  • Migration 工具與各 Provider 的 JSON 改善。
  • SQL Server 向量索引與近似向量搜尋 (Experimental)。

【可能要注意的 Breaking Changes】

  • IHost.RunAsync / StopAsync 在 BackgroundService 失敗時會拋出例外。
  • 部分 Microsoft.Extensions.* 套件併入 Shared Framework。
  • DateOnly / TimeOnly 的 TryParse 對無效輸入會拋出例外。
  • MemoryStream 最大容量與例外行為調整。
  • TAR 讀取會驗證 Header Checksum;ZipArchive.CreateAsync 改為立即載入 Entry。
  • SslStream Server 端預設停用 AIA 憑證下載。
  • macOS 移除 DSA。
  • Native AOT 在 Unix 的原生程式庫輸出加上 lib 前綴。
  • VSTest 移除 Newtonsoft.Json 相依。

【延伸閱讀】

Notes on .NET 11 (STS, released Nov 2026) and C# 15. Covers union types, closed hierarchies, collection expression arguments, extension indexers, labeled break/continue, runtime async, higher CPU baselines, Process.RunAndCaptureText, and updates to the SDK, ASP.NET Core and EF Core 11, plus breaking changes.


Comments

Be the first to post a comment

Post a comment