.NET 11 nähert sich seiner endgültigen Veröffentlichung: Die Plattform hat bereits das Release-Candidate-Stadium erreicht, und die allgemein verfügbare Version wird im November 2026 erscheinen. Das Update erstreckt sich über das gesamte Ökosystem. Die Plattform erscheint mit C# 15 – mit Union-Typen, geschlossenen Hierarchien und einem überarbeiteten Speichersicherheitsmodell. Windows Forms erhält einen Manager für den Kiosk-Modus und eine feingranulare Steuerung des Zeichnens, EF Core 11 erweitert die LINQ-Unterstützung und die Volltextsuche, ASP.NET Core bringt eine Reihe von Blazor-Verbesserungen mit, und die Laufzeit beschleunigt Asynchronität, Interface-Dispatch und JIT-Optimierungen.
Dieser Überblick behandelt die bedeutendsten Änderungen in .NET 11 in jedem Bereich: was hinzugekommen ist, wie man es verwendet und was bei der Migration zu beachten ist.
Die fünfzehnte Version der Sprache macht das Typsystem ausdrucksstärker und gibt Ihnen eine feinere Kontrolle über unsicheren Code.
Das with(...)-Konstrukt, das als erstes Element einer Collection Expression platziert wird, übergibt Argumente direkt an den Konstruktor oder die Factory-Methode der zugrunde liegenden Sammlung. Auf diese Weise werden Parameter wie die anfängliche Kapazität oder ein Comparer direkt in der Initialisierungssyntax angegeben:
string[] values = ["one", "two", "three"]; List<string> names = [with(capacity: values.Length * 2), ..values]; HashSet<string> set = [with(StringComparer.OrdinalIgnoreCase), "Hello", "HELLO", "hello"];
Ein Wert, der zu genau einem von mehreren Falltypen (case types) gehört, wird mit dem union-Schlüsselwort beschrieben:
public record class Cat(string Name); public record class Dog(string Name); public record class Bird(string Name); public union Pet(Cat, Dog, Bird);
Der closed-Modifizierer erlaubt Vererbung nur innerhalb der deklarierenden Assembly: Die Menge der direkten Nachkommen wird zur Kompilierzeit festgelegt.
public closed record class GateState; public record class Closed : GateState; public record class Open(float Percent) : GateState;
Der extension-Block unterstützt jetzt Indexer: Der Empfänger wird indiziert, als wäre der Indexer in seinem Typ deklariert. Da es sich um einen Instanzmember handelt, muss der Block einen benannten Empfängerparameter deklarieren.
Beide Anweisungen können jetzt die Bezeichnung (Label) eines umschließenden Konstrukts annehmen. Dadurch entfallen logische Flags und goto bei der Steuerung des Ablaufs verschachtelter Schleifen:
outer: for (int row = 0; row < grid.Height; row++) { for (int column = 0; column < grid.Width; column++) { if (grid[row, column].IsBlocked) continue outer; if (grid[row, column].IsGoal) break outer; } }
Ab C# 15 beginnt eine über mehrere Releases angelegte Überarbeitung des Speichersicherheitsmodells. Der unsafe-Kontext ist an Operationen gebunden, die tatsächlich nicht verwalteten Speicher berühren, und nicht an die bloße Anwesenheit von Zeigern. Ein Member wird als requires-unsafe markiert, und die Verantwortung für die Prüfung verlagert sich auf den aufrufenden Code; die Tatsache, dass die Regeln angewendet wurden, wird durch das Attribut MemorySafetyRulesAttribute vermerkt. Ein neues Schlüsselwort, safe, wird ebenfalls eingeführt – für Member und extern-Felder in Typen mit explizitem oder erweitertem Layout.
Im Vorschau-Modus sind die Zeigeranforderungen gelockert: Das Deklarieren eines Zeigertyps, das Nehmen einer Adresse mit &, die fixed-Anweisung, die Umwandlung von stackalloc in einen Zeiger und sizeof für nicht verwaltete Typen erfordern kein unsafe mehr. Dereferenzierung (*p), Memberzugriff (p->member), Indexzugriff (p[i]) und Aufruf über einen Zeiger erfordern weiterhin unsafe. Der neue Ausdruck unsafe(expression) begrenzt den unsafe-Kontext auf einen einzelnen Ausdruck – er ist praktisch in Feldinitialisierern und Konstruktoren sowie in catch-Filtern.
Zur Aktivierung sind LangVersion=preview und AllowUnsafeBlocks erforderlich; die aktualisierten Regeln werden über den Feature-Switch updated-memory-safety-rules aktiviert.
Das Update berücksichtigt die praktischen Bedürfnisse von Entwicklern von Desktop-Anwendungen.
KioskModeManager macht eigene Logik zur Fensterverwaltung überflüssig: Er sichert den Zustand des Formulars beim Eintritt in den und Austritt aus dem Vollbildmodus, blockiert das Abschalten des Bildschirms und den Ruhezustand, blendet den Cursor nach Inaktivität aus und behandelt Tastenkombinationen. Der Manager arbeitet mit ContainerControl und damit sowohl mit Form als auch mit UserControl.
Application.SystemVisualSettings stellt einen einzigen Schnappschuss der visuellen Systemgestaltung bereit: Akzentfarbe, hoher Kontrast, Sichtbarkeit von Tastaturhinweisen, Animation, Metriken des Fokusrands und Textskalierung. Das Ereignis SystemVisualSettingsChanged ermöglicht die Aktualisierung nur des betroffenen Teils der Benutzeroberfläche, während die Eigenschaft ChangedCategories genau verrät, was sich geändert hat. Steuerelemente können die Methode OnSystemVisualSettingsChanged überschreiben.
Die Enumeration FormRevealMode gibt der Anwendung die Kontrolle über den Zeitpunkt, zu dem das Formular beim Start erscheint. Dadurch lässt sich vermeiden, dass das Fenster kurz ohne seine visuelle Gestaltung aufblitzt. Der Deferred-Modus aktiviert die verzögerte Anzeige, während Classic das bisherige Verhalten beibehält.
Die Schnittstelle ISupportSuspendPainting und die Methode ControlMutationExtensions.SuspendPainting fassen die Paare BeginUpdate/EndUpdate und SuspendLayout/ResumeLayout in einem einzigen IDisposable-Bereich zusammen, während die Eigenschaft LayoutSuspendTraversal bestimmt, ob die Aussetzung nur das Zielobjekt oder auch seine untergeordneten Elemente umfasst. Das dämpft kaskadierende Layoutneuberechnungen und Flackern – besonders bei verschachtelten TableLayoutPanel-Steuerelementen mit automatischer Größenanpassung. ComboBox, ListBox, ListView, RichTextBox und TreeView implementieren die neue Schnittstelle bereits.
Die elfte Version von EF Core vertieft die Unterstützung für relationale Szenarien und Suche.
Der Operator FullJoin bewahrt Zeilen aus beiden Eingabesammlungen und wird in FULL JOIN übersetzt:
var results = await context.Customers .FullJoin( context.Orders, c => c.Id, o => o.CustomerId, (c, o) => new { Customer = c, Order = o }) .ToListAsync();
Die Methoden MaxByAsync und MinByAsync (und ihre synchronen Entsprechungen) werden jetzt nach SQL übersetzt. Dadurch lässt sich das Element mit dem maximalen oder minimalen Selektorwert ermitteln, ohne alle Datensätze zu laden:
var blogWithMostPosts = await context.Blogs.MaxByAsync(b => b.Posts.Count());
Die Funktion prüft, ob ein JSON-Pfad in einem Dokument vorhanden ist; auf SQL Server wird sie in JSON_PATH_EXISTS übersetzt (ab SQL Server 2022).
Volltextkataloge und -indizes werden direkt im Modell konfiguriert, sodass Migrationen sie automatisch anlegen. Die Vektorsuche in SQL Server wird mit volltextbasierten Tabellenwertfunktionen zur hybriden Suche kombiniert: Exakte Treffer aus der Volltextsuche und semantisch nahe Ergebnisse aus Vektoren werden per Rangfolge zusammengeführt. Die Unterstützung von FullJoin rundet das Muster zusätzlich ab:
var results = await context.Articles .FreeTextTable<Article, int>(textualQuery, topN: k) .Join(context.Articles, fts => fts.Key, a => a.Id, (fts, a) => new { Article = a, fts.Rank }) .FullJoin( context.Articles.VectorSearch(a => a.Embedding, queryEmbedding, "cosine") .OrderBy(r => r.Distance) .Take(k) .WithApproximate(), fts => fts.Article.Id, vs => vs.Value.Id, (fts, vs) => new { Article = fts != null ? fts.Article : vs.Value, FullTextRank = fts == null ? null : (int?)fts.Rank, VectorDistance = vs == null ? null : (double?)vs.Distance }) .Select(x => new { x.Article, RrfScore = (x.FullTextRank == null ? 0.0 : 1.0 / (k + x.FullTextRank.Value)) + (x.VectorDistance == null ? 0.0 : 1.0 / (k + x.VectorDistance.Value)) }) .OrderByDescending(x => x.RrfScore) .Take(10) .Select(x => x.Article) .ToListAsync();
Die GroupBy-Übersetzung wurde überarbeitet: Abfragen können jetzt Navigationen und Joins auf dem Ergebnis „Top-Element pro Gruppe“ aufbauen, Aggregate über Referenznavigationen laufen vor der Gruppierung über Joins statt über korrelierte Unterabfragen, und Nicht-Entitäts-Projektionen – anonyme Typen und DTOs – werden über Joins und Gruppierungen korrekt materialisiert.
Bei aufgeteilten Abfragen (AsSplitQuery()) fügt EF Core für Referenznavigationen keine redundanten Joins mehr hinzu und dupliziert ihre Schlüssel nicht mehr in ORDER BY: Der Schlüssel einer Referenznavigation ergibt sich bereits aus dem Schlüssel des übergeordneten Objekts über den Fremdschlüssel. In Benchmarks werden Gewinne von bis zu 29% bei einer aufgeteilten Abfrage und bis zu 22% durch das Entfernen des redundanten ORDER BY genannt.
ASP.NET Core 11 entwickelt Blazor weiter in Richtung Flexibilität und Leistung.
Standardmäßig werden die serverseitigen Werte CurrentCulture und CurrentUICulture im Komponentenzustand gespeichert und auf dem Client angewendet, bevor zusätzliche Assemblys geladen werden. Dieses Verhalten lässt sich über WebAssemblyComponentsOptions.UseCultureFromServer = false deaktivieren.
Cookie-basierte HTTP-Sitzungsdaten stehen jetzt während des statischen Renderings zur Verfügung – nützlich für einen Warenkorb oder den Fortschritt mehrstufiger Formulare. Anders als bei ITempData werden Werte nach dem Lesen nicht gelöscht und leben während der gesamten Sitzung. Sie benötigen AddSession() und UseSession().
Eine integrierte Blazor-Komponente für bedingtes Rendering je nach Hosting-Umgebung. Sie akzeptiert die Parameter Include und Exclude und gleicht Werte ohne Beachtung der Groß-/Kleinschreibung ab; die Semantik entspricht dem MVC-EnvironmentTagHelper.
WASM-Anwendungen unterstützen IHostedService-Hintergrunddienste im Browser – das bringt Parität mit Blazor Server und ermöglicht Szenarien wie periodische Datenaktualisierung, Echtzeit-Updates und Hintergrundverarbeitung.
Die Methode WithBrowserOptions legt Client-Startparameter in C# fest statt eines manuellen Blazor.start-Aufrufs: Protokollierungsgrad, Wiederverbindung des Interactive Servers, DOM-Erhaltung bei erweiterter Navigation, Name der Umgebung, Kultur und WebAssembly-Umgebungsvariablen:
app.MapRazorComponents<App>()
.WithBrowserOptions(options =>
{
options.InteractiveServer.ReconnectionDialogId = "reconnect-dialog";
options.InteractiveServer.ReconnectionMaxRetries = 10;
options.InteractiveWebAssembly.EnvironmentVariables["OTEL_EXPORTER_OTLP_ENDPOINT"] = "https://localhost:4318";
options.StaticServer.PreserveDom = true;
options.InteractiveWebAssembly.ApplicationCulture = "en-ca";
options.LogLevel = LogLevel.Warning;
});
Das Paket Microsoft.AspNetCore.Components.Server.AutoPause setzt den Circuit in den Ruhezustand, wenn die Registerkarte ausgeblendet ist, und gibt dadurch Serverarbeitsspeicher und SignalR-Verbindungen frei. Nach einer konfigurierbaren Verzögerung (standardmäßig zwei Minuten) wird der Circuit angehalten; kehrt der Benutzer früher zurück, tritt die Pausierung nicht in Kraft.
Die Komponente CacheView speichert das Rendering-Ergebnis eines Razor-Teilbaums während des statischen SSR zwischen. Bei einem Cache-Treffer wird das Markup wiedergegeben, ohne untergeordnete Komponenten zu instanziieren oder ihren Lebenszyklus auszuführen – praktisch für aufwendige, überwiegend statische Bereiche:
<CacheView VaryByQuery="category" ExpiresAfter="TimeSpan.FromMinutes(5)"> <ProductList Category="@Category" /> </CacheView>
Eine Sammlung von Komponenten für agentische Schnittstellen: Streaming von Fortschritt in Echtzeit, Visualisierung der Argumentation und des Fortschritts des Agenten, Bestätigungsaufforderungen vor Tool-Aufrufen, multimodale Eingabe und Zustandssynchronisation zwischen Anwendung und Agent. Die Komponenten sind experimentell, daher kann sich die API bis zu ihrer Stabilisierung ändern.
Die Laufzeit beschleunigt Asynchronität und Interface-Dispatch, während CoreCLR in WebAssembly dem praktischen Einsatz in Blazor näher rückt.
Der Runtime-Async-Mechanismus ist nicht mehr experimentell: Die Laufzeit wird jetzt standardmäßig mit seiner Unterstützung erstellt. Zusätzlich hat der JIT gelernt, spezialisierte Versionen synchroner Methoden zu kompilieren, die Task zurückgeben, wodurch der Overhead asynchroner Aufrufe deutlich sinkt.
Der Interface-Dispatch in NativeAOT wurde dank eines gemeinsamen Helper-Mechanismus schneller. Das reduzierte die Menge des Binärcodes an Aufrufstellen und verbesserte den Durchsatz in Szenarien mit intensiver Schnittstellennutzung.
Die Arbeit am JIT geht in mehreren Bereichen weiter: Eliminierung von Grenzprüfungen, Devirtualisierung und konstante Faltung. Auf x64 wird Math.BigMul jetzt in eine einzelne MUL-Instruktion kompiliert.
CoreCLR in WebAssembly hat einen wichtigen Meilenstein erreicht: Es besteht die vollständige Bibliothekstestsuite. Das rückt den Moment näher, in dem Blazor WebAssembly auf CoreCLR laufen kann.
.NET 11 ist ein Release, bei dem die Änderungen gleichmäßig über das gesamte Ökosystem verteilt sind, statt sich in einer einzelnen Sprache oder einem Framework zu konzentrieren. C# 15 setzt den Kurs in Richtung strengere Typisierung und explizites Management von unsicherem Code; Windows Forms geht auf praktische Bedürfnisse von Desktop-Entwicklern ein; EF Core 11 vertieft die Unterstützung relationaler und hybrider Suchszenarien; ASP.NET Core treibt Blazor weiter in Richtung Flexibilität und Leistung; die Laufzeit beschleunigt Asynchronität, Interface-Dispatch und JIT, während CoreCLR in WebAssembly den praktischen Einsatz in Blazor anstrebt.
Einige Funktionen – vor allem die mit der Speichersicherheit zusammenhängenden – sind als Initiative über mehrere Releases angekündigt und werden schrittweise ausgerollt. Teams, die eine Migration planen, sollten vorab einschätzen, welche Änderungen ihre Codebasis unmittelbar betreffen und welche sich später ohne Eile übernehmen lassen. Da sich die Plattform bereits im Release-Candidate-Stadium befindet, ist jetzt der ideale Zeitpunkt, Ihre Projekte am .NET-11-Release-Candidate zu testen: So sind Sie im November, wenn das Release erscheint, bestens vorbereitet.