.NET 11 is moving toward its final release: the platform has already reached the Release Candidate stage, and the general availability version will ship in November 2026. The update is spread across the entire ecosystem. The platform ships with C# 15 — featuring union types, closed hierarchies, and a reworked memory safety model. Windows Forms gets kiosk mode and fine-grained painting control, EF Core 11 extends LINQ and full-text search support, ASP.NET Core brings a set of Blazor improvements, and the runtime speeds up asynchrony, interface dispatch, and JIT optimizations.
This overview covers the most significant .NET 11 changes in each area: what has been added, how to use it, and what to watch out for during migration.
Â
Â
The fifteenth version of the language makes the type system more expressive and gives you finer control over unsafe code.
The with(...) construct, placed as the first element of a collection expression, passes arguments straight to the underlying collection's constructor or factory method. This way, parameters such as initial capacity or a comparer are specified right in the initialization syntax:
string[] values = ["one", "two", "three"]; List<string> names = [with(capacity: values.Length * 2), ..values]; HashSet<string> set = [with(StringComparer.OrdinalIgnoreCase), "Hello", "HELLO", "hello"];
A value that belongs to exactly one of several case types is described with the union keyword:
public record class Cat(string Name); public record class Dog(string Name); public record class Bird(string Name); public union Pet(Cat, Dog, Bird);
The closed modifier allows inheritance only within the declaring assembly: the set of direct descendants is fixed at compile time.
public closed record class GateState; public record class Closed : GateState; public record class Open(float Percent) : GateState;
The extension block now supports indexers: the receiver is indexed as if the indexer were declared in its type. Since this is an instance member, the block must declare a named receiver parameter.
Both statements can now take the label of an enclosing construct. This eliminates the need for logical flags and goto when controlling the flow of nested loops:
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; } }
Starting with C# 15, a multi-release overhaul of the memory safety model begins. The unsafe context is bound to operations that actually touch unmanaged memory, rather than to the mere presence of pointers. A member is marked as requires-unsafe, and the responsibility for auditing shifts to the calling code; the fact that the rules were applied is recorded by the MemorySafetyRulesAttribute attribute. A new keyword, safe, is also introduced — for members and extern fields in types with explicit or extended layout.
In preview mode, pointer requirements are relaxed: declaring a pointer type, taking an address with &, the fixed statement, converting stackalloc to a pointer, and sizeof for unmanaged types no longer require unsafe. Dereferencing (*p), member access (p->member), index access (p[i]), and invocation through a pointer still require unsafe. The new unsafe(expression) expression scopes the unsafe context to a single expression — it comes in handy in field initializers and constructors, as well as in catch filters.
Enabling it requires LangVersion=preview and AllowUnsafeBlocks; the updated rules are activated by the updated-memory-safety-rules feature switch.
Â
Â
The update addresses practical needs of desktop application developers.
KioskModeManager eliminates the need for your own window-management logic: it saves the form's state when entering and leaving full-screen mode, blocks display shutdown and sleep, hides the cursor after inactivity, and handles key combinations. The manager works with ContainerControl, and therefore with both Form and UserControl.
Application.SystemVisualSettings provides a single snapshot of the system's visual styling: accent color, high contrast, keyboard cue visibility, animation, focus border metrics, and text scaling. The SystemVisualSettingsChanged event lets you update only the affected portion of the UI, while the ChangedCategories property tells you exactly what changed. Controls can override the OnSystemVisualSettingsChanged method.
The FormRevealMode enumeration gives the application control over the moment the form appears at startup. This helps prevent the window from briefly flashing without its visual styling. The Deferred mode enables deferred display, while Classic preserves the previous behavior.
The ISupportSuspendPainting interface and the ControlMutationExtensions.SuspendPainting method combine the BeginUpdate/EndUpdate and SuspendLayout/ResumeLayout pairs into a single IDisposable scope, while the LayoutSuspendTraversal property determines whether the suspension covers only the target object or its children as well. This curbs cascading layout recalculations and flicker — especially in nested TableLayoutPanel controls with automatic sizing. ComboBox, ListBox, ListView, RichTextBox, and TreeView already implement the new interface.
Â
Â
The eleventh version of EF Core deepens support for relational scenarios and search.
The FullJoin operator preserves rows from both input collections and translates to FULL JOIN:
var results = await context.Customers .FullJoin( context.Orders, c => c.Id, o => o.CustomerId, (c, o) => new { Customer = c, Order = o }) .ToListAsync();
The MaxByAsync and MinByAsync methods (and their synchronous counterparts) are now translated to SQL. This makes it possible to find the element with the maximum or minimum selector value without loading all records:
var blogWithMostPosts = await context.Blogs.MaxByAsync(b => b.Posts.Count());
The function checks whether a JSON path exists in a document; on SQL Server it translates to JSON_PATH_EXISTS (starting with SQL Server 2022).
Full-text catalogs and indexes are configured directly in the model so that migrations create them automatically. SQL Server vector search is combined with full-text table-valued functions into hybrid search: exact matches from full-text search and semantically close results from vectors are merged by ranking. Support for FullJoin makes the pattern even more complete:
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();
GroupBy translation has been reworked: queries can now compose navigations and joins on top of the "top element per group" result, aggregates over reference navigations go through joins before grouping rather than through correlated subqueries, and non-entity projections — anonymous types and DTOs — are materialized correctly through joins and groupings.
With split queries (AsSplitQuery()), EF Core no longer adds redundant joins for reference navigations and no longer duplicates their keys in ORDER BY: the key of a reference navigation is already determined by the parent's key through the foreign key. Benchmarks mention gains of up to 29% for a split query and up to 22% from removing the redundant ORDER BY.
Â
Â
ASP.NET Core 11 continues to evolve Blazor toward flexibility and performance.
By default, the server-side CurrentCulture and CurrentUICulture values are stored in component state and applied on the client before auxiliary assemblies load. This behavior can be disabled via WebAssemblyComponentsOptions.UseCultureFromServer = false.
Cookie-based HTTP session data became available during static rendering — useful for a shopping cart or multi-step form progress. Unlike ITempData, values are not cleared after being read and live for the entire session. You will need AddSession() and UseSession().
A built-in Blazor component for conditional rendering based on the hosting environment. It accepts Include and Exclude parameters, matches values case-insensitively; the semantics match the MVC EnvironmentTagHelper.
WASM applications support IHostedService background services in the browser — reaching parity with Blazor Server and enabling scenarios such as periodic data refresh, real-time updates, and background processing.
The WithBrowserOptions method sets client startup parameters in C# instead of a manual Blazor.start call: logging level, Interactive Server reconnection, DOM preservation during enhanced navigation, environment name, culture, and WebAssembly environment variables:
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;
});
The Microsoft.AspNetCore.Components.Server.AutoPause package suspends the circuit when the tab is hidden, freeing server memory and SignalR connections. After a configurable delay (two minutes by default), the circuit is paused; if the user returns earlier, the pause does not take effect.
The CacheView component caches the rendering result of a Razor subtree during static SSR. On a cache hit, the markup is reproduced without instantiating or running the lifecycle of child components — handy for expensive, mostly static sections:
<CacheView VaryByQuery="category" ExpiresAfter="TimeSpan.FromMinutes(5)"> <ProductList Category="@Category" /> </CacheView>
A set of components for agentic interfaces: real-time streaming of progress, visualization of agent reasoning and progress, confirmation prompts before tool calls, multimodal input, and state synchronization between the application and the agent. The components are experimental, so the API may change until they are stabilized.
Â
Â
The runtime speeds up asynchrony and interface dispatch, while CoreCLR in WebAssembly moves closer to practical use in Blazor.
The Runtime Async mechanism is no longer experimental: the runtime is now built with its support by default. Additionally, the JIT learned to compile specialized versions of synchronous methods that return Task, significantly reducing the overhead of asynchronous calls.
Interface dispatch in NativeAOT became faster thanks to a shared helper mechanism. This reduced the amount of binary code at call sites and improved throughput in scenarios with heavy interface usage.
Work on the JIT continues in several areas: bounds check elimination, devirtualization, and constant folding. On x64, Math.BigMul now compiles into a single MUL instruction.
CoreCLR in WebAssembly has reached an important milestone: it passes the full library test suite. This brings closer the moment when Blazor WebAssembly will be able to run on CoreCLR.
Â
Â
.NET 11 is a release in which changes are distributed evenly across the entire ecosystem rather than concentrated in a single language or framework. C# 15 sets the course toward stricter typing and explicit management of unsafe code; Windows Forms responds to practical needs of desktop developers; EF Core 11 deepens support for relational and hybrid search scenarios; ASP.NET Core continues to advance Blazor toward flexibility and performance; the runtime speeds up asynchrony, interface dispatch, and JIT, while CoreCLR in WebAssembly approaches practical use in Blazor.
Some features — primarily those related to memory safety — are announced as a multi-release initiative and will be rolled out gradually. Teams planning a migration should assess in advance which changes affect their codebase directly and which can be adopted later without haste. Since the platform is already at the Release Candidate stage, now is the perfect time to test your projects on the .NET 11 release candidate: that way, when the November release arrives, you'll meet it fully prepared.