WIADOMOśCI Z BRANżY

Twoj przewodnik po Microsoft Build 2025 - Co deweloperzy korzystający z Iron Software powinni obserwować

.NET 11 osiąga trzeci podgląd około sześciu miesięcy przed planowanym GA w listopadzie 2026, a w przeciwieństwie do Preview 1 i 2, które były głównie rurowaniem, Preview 3 to ten, gdzie można faktycznie poczuć kształt wydania.

Runtime Async przestaje być eksperymentem "preview-feature gate", JIT zyskuje kolejną porcję darmowych optymalizacji, ASP.NET Core otrzymuje Zstandard od razu, a unie typów C# 15 - funkcja językowa, o którą pytano od ponad dekady.

To nie jest wydanie LTS, .NET 11 to kolejna wersja Standard Term Support, z 24 miesiącami wsparcia, co już zmienia kalkulacje dotyczące tego, czy warto się aktualizować. Poniżej znajduje się to, co naprawdę warto twojej uwagi jako dewelopera, i gdzie nadal są niedoskonałości.

Unie typów C# 15: Duża zmiana

Jesli pisales biblioteki OneOf<T1, T2>, recznie tworzac zamkniete hierarchie rekordow, lub tylko zazdrosciles programistom F#, to jest to najwazniejsza informacja. C# 15 wprowadza slowo kluczowe union, ktore deklaruje, ze wartosc jest dokladnie jednym z okreslonego zestawu typow, z wymuszona przez kompilator kompletnoscia. Typy unijne pojawiły się w Podglądzie 2; Podgląd 3 doskonali wsparcie IDE wokół nich.

Podejście zespołu C# jest bliższe unii typów niż rozróżników unii F#: typy członkowskie to istniejące typy, które zdefiniowałeś osobno, a nie przypadki tagów zagnieżdżone wewnątrz deklaracji unii. Unia to w zasadzie struktura, która obudowuje obiekt i ogranicza, co może do niej wejść. Z punktu widzenia miejsca wywolania, wydaje sie to natywne - niejawna konwersja z typow czlonkowskich do unii, wyczerpujace wyrazenia switch w Pet.Value, i nie potrzeba domyslnej galezi, gdy kompilator zna wszystkie przypadki.

[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
$vbLabelText   $csharpLabel

Zalety sa rzeczywiste: zamkniete typy, brak niepoprawnych stanow, kompletnosc sprawdzana podczas kompilacji zamiast o NotImplementedExceptionat 3 nad ranem. Dodaj rekina do unii, a każdy switch na Pet rozświetla się ostrzeżeniami, dopóki go nie obsłużysz.

Wady są również realne i warto je wskazać w każdej rzetelnej recenzji. Eksponowana wartościowa właściwość Object Value to zapach - trwa otwarta dyskusja na GitHubie o ukrywaniu jej za czymś bardziej bezpiecznym typowo. Publiczne konstruktory implicitATYPE typu akceptowalnego przez unię, co nie jest ani odkrywalne, ani jawne. Interop F# jest nierozwiązany (dwa modele są fundamentalnie różne). Szersza historia wyczerpującości nadal ma luki: zamknięte hierarchie i zamknięte enumeracje, dwa wnioski, które byłyby obrazem dopełnającym, nadal są propozycjami. Unie same w sobie są świetne. Unie plus zamknięte enumeracje plus zamknięte hierarchie byłyby generacyjną zmianą. Nie jesteśmy jeszcze tam.

Runtime Async V2 i ulepszenia JIT

Runtime Async to cicha przepisa .NET dotycząca wyglądu async/await rzeczywiście wykonuje się. Zamiast tego, żeby kompilator C# emitował klasę state-machine na metodę asynchroniczną, samo środowisko wykonawcze zarządza zawieszeniem i wznowieniem. Widoczny zwrot: czystsze ślady stosu, mniejsze alokacje i debugger, który nie zmusza do przewijania przez ramki MoveNext, aby znaleźć swój własny kod.

W podgladzie 3, Runtime Async usuwa wymog EnablePreviewFeatures. Wciaz przelaczasz klucz funkcyjny - <Features>runtime-async=on</Features> - ale nie musisz juz wybierac kazdego wywolania API do terytorium podgladu. Wsparcie NativeAOT i ReadyToRun wylądowało w tej wersji podglądu, co zamyka lukę między scenariuszami JIT i AOT. Obiekty kontynuacji są bardziej agresywnie ponownie wykorzystywane, a zmienne lokalne, które się nie zmieniały, nie są zapisywane podczas zawieszenia. W ścieżkach kodu ciężkich w async - pomyśl o pipeline Kestrel lub pracowniku zapytań EF Core - to znaczący spadek presji alokacyjnej.

JIT zdobyło swoją zwykłą porcję "twój istniejący kod jest teraz szybszy, nie rób nic":

  • Wyrażenia switch z wieloma celami, takie jak x jest 0 lub 1 lub 2 lub 3 lub 4, teraz składają się w kontroli bezgałęziowe.
  • Kontrole zakresu dla wartości[^1] + patternów wartości[^2] są bardziej agresywnie eliminowane, a powszechne przypadki i + cns < len w pętlach składają się czysto.
  • Rzutowanie unsigned-int-to-float i unsigned-int-to-double jest szybsze na sprzęcie x86 przed AVX-512 - nieczęste, ale realne, jeśli jesteś na starszych maszynach.

Uzytkownicy WebAssembly dostaja ladowanie ladunku WebCIL bezposrednio w czasie wykonywania, lepsze symbole debugowania, oraz float[] / Span<float> / ArraySegment<float> marshaling bez narzutu zwrotnego przejazdu. Żadne z tych nie są indywidualnie dramatyczne, ale razem są rodzajem komponowania pracy, która sprawia, że Blazor WASM czuje się mniej jak kompromis.

Haczyk to dolna granica sprzętowa. .NET 11 podnosi minimalne wymagania zestawu instrukcji na x86/x64 i Arm64. Apple Silicon i większość Linux SBC są w porządku - gotowy cel ReadyToRun na Arm64 dodaje jedynie LSE - ale bardzo stary sprzęt x86 nie spełnia wymagań. Przeprowadź audyt swojej floty, zanim założysz aktualizację na miejscu.

ASP.NET Core i Blazor

Zstandard is the headliner here. ASP.NET Core teraz obsługuje zstd zarówno dla kompresji odpowiedzi, jak i dekompresji żądań, i jest to domyślnie włączone, gdy dodajesz middleware. Konfiguracja jest w takim kształcie, jakiego byś się spodziewał:

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)
$vbLabelText   $csharpLabel

Dla API obsługujących JSON lub tekst dla klientów już obsługujących zstd - coraz powszechniej w ekosystemach mobilnych i powiązanych z gRPC - to jest mierzalna wygrana pod względem przepustowości bez zależności od biblioteki zewnętrznej. Jest to także, co ważne, wkład społecznościowy, a nie wewnętrzny projekt Microsoft, co jest zdrowym sygnałem.

Virtualize<TItem> Blazor w koncu przestaje zakladac, ze kazdy wiersz ma taka sama wysokosc. To była długotrwała irytacja: każda lista z zmienną zawartością - komentarze, wiadomości na czacie, cokolwiek z tekstem zawijanym - wymagała ręcznych obejść. Teraz komponent mierzy elementy w czasie wykonywania. Wydanie Preview 3 rowniez naprawia grupe bledow Blazor: odniesienie do null w Virtualize, wykrywanie scroll-containera przy overflow-x, szablon Web Workera w opublikowanych aplikacjach WASM, TempData przypadki skrajne lazy loading, oraz IJSObjectReference przeciek w ResourceCollectionProvider. Indywidualnie małe, zbiorczo to rodzaj czyszczenia, który sygnalizuje dojrzewanie frameworka poza fazę "nowość przy każdym wydaniu".

Kestrel również zaczyna przetwarzać żądania HTTP/3 bez czekania na strumień kontrolny i ramkę SETTINGS, co zmniejsza opóźnienie pierwszego żądania w nowych połączeniach. Jeśli mierzyłeś HTTP/3 P99s i zauważyłeś dziwne ogony zimnego startu, to jest twoja poprawka.

.NET MAUI

MAUI w Preview 3 koncentruje się głównie na zamykaniu luk, które sprawiały, że wyglądała na wersję beta przez zbyt długi czas. Kontrola Map otrzymuje grupowanie pinow, niestandardowe ikony pinow, niestandardowe stylizowanie JSON i zdarzenia klikniec na kolach, wielokatow i linii poliliniowych - wszystko, czego potrzebuja rzeczywiste interfejsy map produkcyjnych i co wczesniej wymagala niestandardowych obslugujacych dla kazdej platformy. Dostępny jest teraz wbudowany LongPressGestureRecognizer bez konieczności tworzenia własnego. Domyślne deklaracje przestrzeni nazw XAML są teraz domyślnie włączone, co skraca szablony na początku każdego pliku.

Rownosc platformowa zyskuje na wartosci: Permissions.PostNotifications jest teraz zaimplementowane na iOS (bylo tylko na Androidzie), a Android zyskuje obsluge podgladowa dla Androida 17 i poziomu API 37.

Uczciwa ocena: to stabilne, rozsądne iteracje, a nie reinwencja. MAUI w 2026 roku jest w znacznie lepszej sytuacji niż MAUI w 2023, ale jeśli odeszłeś od niego wcześniej, samo Preview 3 nie przyciągnie cię z powrotem. Jeśli już korzystasz z MAUI, to są dokładnie te zmiany QoL, które chcesz.

SDK, CLI i .NET watch

To sekcja, w której te małe rzeczy sumują się. Kilka z nich, które, moim zdaniem, rzeczywiście zmieniają codzienny przepływ pracy:

.NET sln może teraz tworzyć i edytować filtry rozwiązań (.slnf) bezpośrednio z CLI. Dla monorepozytoriów i dużych rozwiązań w stylu Microsoft, otwieranie 200-projektowego SLN-u do pracy nad trzema z nich było realnym kosztem. Teraz możesz określić zakres z terminala:

dotnet new slnf --name MyApp.slnf
dotnet sln MyApp.slnf add src/Lib/Lib.csproj
dotnet new slnf --name MyApp.slnf
dotnet sln MyApp.slnf add src/Lib/Lib.csproj
SHELL

Aplikacje oparte na plikach (workflow aplikacji .NET run app.cs) w końcu obsługują #:include, co oznacza, że skrypty C# mogą dzielić pomocnicze na oddzielne pliki. W połączeniu z automatycznym uzupełnianiem w edytorze dla dyrektywy w Roslyn, to przemieszcza aplikacje oparte na plikach z "zabawka" do "może być używana do rzeczywistych narzędzi automatyzacji" - niszy, którą przez lata posiadały PowerShell i małe skrypty Pythona.

.NET run -e FOO=BAR pozwala przekazać zmienne środowiskowe w wierszu poleceń bez eksportowania stanu powłoki lub edytowania profili uruchomieniowych. Drobiazg, ale jesli kiedykolwiek miales trzy terminale otwarte z rozna wartoscia ASPNETCORE_ENVIRONMENT, znasz ten bol.

.NET watch integruje się z hostami aplikacji Aspire, automatycznie uruchamia się po awarii przy następnym zmianie pliku i łagodniej obsługuje Ctrl+C dla WinForms i WPF (stały problem). .NET format akceptuje --framework dla projektów docelowych. .NET test w trybie MTP obsługuje --artifacts-path. I .NET tool exec / dnx nie wymaga już dodatkowej zgody, co było punktem tarcia dla jednorazowych uruchomień narzędzi.

Punkty bólu

Zbalansowana recenzja musi obejmować ostre krawędzie, a Preview 3 je ma.

Historia narzędzi jest surowa. Visual Studio 2026 jest wciąż w wersji zapoznawczej sześć miesięcy po wydaniu .NET 10, a agenci budowlani hostowani przez Microsoft nie mają jeszcze stabilnego wsparcia dla VS 2026. Zmiana w wydaniu poprawki SDK .NET 10 wymagała MSBuild 18 (VS 2026), co jest czystym naruszeniem gwarancji semver promowanych przez Microsoft. Każdy, kto uruchamia CI na agentach hostowanych przez Microsoft, musiał przypiąć SDK 10.0.4 lub przejść na obrazy budowania w wersji zapoznawczej. Jeśli rozważasz przeniesienie CI na zapoznawcze wersje .NET 11, spodziewaj się więcej tego samego - wersje SDK w zapoznaniu, zgodnie z przyznaniem zespołu, większyły problemy w wersjach 10.0.2 i 10.0.3 przed stabilizacją.

Async Runtime nadal jest opcjonalne. Nawet z usunieta bramka funkcji podgladu, musisz przelaczyc runtime-async=on. To w porządku dla kodu na nowym miejscu; dla bibliotek wydawanych w NuGet nie możesz nadal przyjąć, że twoi konsumenci mają przełącznik włączony, więc praktyczne korzyści są odłożone do momentu, gdy funkcja stanie się domyślną (nie w .NET 11).

Wymogi sprzętowe zmieniają się. Minimalne wymagania zestawu instrukcji x86/x64 zostały podniesione. Większość zespołów tego nie zauważy. Niektóre zespoły - i dowiedzą się przy wdrożeniu, jeśli wcześniej tego nie sprawdzą.

Nie LTS, ale STS. .NET 11 jest obsługiwane przez 24 miesiące. .NET 10, obecne LTS, otrzymuje 36 miesięcy. Dla firm z powolnym cyklem aktualizacji, .NET 10 wciąż pozostaje bardziej konserwatywnym wyborem, a przyjęcie .NET 11 oznacza zobowiązanie się do kolejnej aktualizacji w 2028 roku. Argumentem za przyjęciem STS są funkcje; argumentem przeciwko jest kalendarz.

Zapowiedź oznacza zapowiedź. To nie jest narzekanie na stabilność - proces zapoznawczy Microsoftu był dobry - ale Preview 3 nie jest kandydatem do wydania. Produkcje wdrożeniowe czekają co najmniej na RC1. Narzędzia wewnętrzne, projekty boczne i eksploracja to aktualnie właściwy zakres.

Werdykt

Jeśli piszesz C# każdego dnia, warto zainstalować i przetestować .NET 11 Preview 3 w tym tygodniu - szczególnie ze względu na włączenie typów związkowych, które są najważniejszą zmianą językową od lat. Jeśli utrzymujesz biblioteki, praca nad JIT i Async Runtime oznacza, że twój kod będzie szybszy na .NET 11 bez zmian, co jest najlepszym rodzajem aktualizacji. Jeśli wydajesz aplikacje MAUI, prace nad Mapą i gestami to prawdziwy postęp.

Jeśli uruchamiasz produktywne obciążenia .NET, odpowiedź brzmi: planuj dalej, obserwuj dalej i zaznacz GA w listopadzie. Rzeczy, które ekscytują, są udostępniane, ale łańcuch narzędzi - VS, agenci budowlani i tempo poprawek SDK - to miejsce, w którym w rzeczywistości tkwi tarcie i to jeszcze nie zostało rozwiązane.

| --- |

Źródła: .NET Blog announcement, What's new in .NET 11 (Microsoft Learn), Runtime release notes, ASP.NET Core release notes, SDK release notes, Explore union types in C# 15.