NewsProgramming Languages

.NET 11 RC1: C# 15 Unions, Runtime Async, Go-Live

.NET 11 RC1 featured image showing dotnet logo with C# 15 union type syntax and clean stack trace comparison

.NET 11 RC1 landed September 8 with something you rarely see on a release candidate: a production go-live support license. Microsoft isn’t asking you to wait for November GA — they’re telling you this is ready. C# 15 defaults on, Runtime Async drops its preview flag, and a stack of practical library improvements ship with it. Here’s what matters and what to do before GA closes.

The Go-Live License Changes the Calculus

.NET 11 RC1 carries a Microsoft support agreement for production use. That’s unusual. Most RC labels mean “almost done, don’t bet your business on it yet.” Not here. If you have a workload that could benefit from testing under real conditions — and filing issues that shape the final GA — now is the time. GA ships in November 2026. The feedback window before that closes fast.

C# 15 Union Types: The Feature the Community Has Been Waiting For

Union types are the headline C# 15 feature, and they’re better than most expected. The syntax is clean: declare a closed set of existing types, get implicit conversions, and let the compiler enforce exhaustiveness in switch expressions.

public union ApiResult<T>(T Value, ApiError Error, ValidationFailure Failure);

string Describe<T>(ApiResult<T> result) => result switch {
    T value              => $"Success: {value}",
    ApiError e           => $"Error {e.Code}: {e.Message}",
    ValidationFailure f  => $"Invalid: {f.Field}"
};
// No default case needed — the compiler knows all possibilities

The key word is “existing.” You’re not rewriting your types into a common hierarchy — you’re composing types that already exist into a named, closed union. Add a fourth case later and the compiler immediately flags every switch expression that doesn’t handle it. That’s the kind of safety net that makes refactoring large codebases significantly less painful.

For anyone using the OneOf library as a workaround, this is the native replacement you’ve been asking for. The new JsonUnionTypeStructuralClassifier in System.Text.Json handles serialization automatically. Closed hierarchies ship alongside unions, preventing derived classes outside the defining assembly and giving library authors proper sealed type hierarchies for exhaustive matching across boundaries.

Runtime Async: Your Stack Traces Finally Make Sense

Runtime Async has been in preview since .NET 11 Preview 1. In RC1, it no longer requires <EnablePreviewFeatures>true</EnablePreviewFeatures> for net11.0 targets — the runtime libraries themselves compile with it enabled. This is the default now.

The practical difference shows up immediately in debuggers and profilers. The old compiler-generated state machine model turns every async method into a tangle of MoveNext, AsyncStateMachine, and mangled generic type names on the call stack. Runtime Async eliminates that. Your methods appear directly on the stack, the way you wrote them — the way synchronous code always has.

Beyond readability: async continuations now opt out of ExecutionContext capture when there’s no ambient state, tail-merged suspension points reduce generated code size, and JIT tiered compilation handles dedicated async paths separately. Warm-up allocations drop, and common await paths speed up. In-process crash reporting on mobile, Linux, and macOS captures the managed stack before the process exits — a genuine win for anyone debugging production crashes on non-Windows platforms.

SDK Wins Worth Knowing

A few practical SDK changes in RC1 that deserve attention:

  • Mobile testing: dotnet test now supports Android, iOS, macOS, and Mac Catalyst projects natively, with device selection and dedicated test templates.
  • CLI env variables: dotnet run -e VAR=VALUE passes environment variables without wrapper scripts.
  • Reproducible containers: Deterministic image digests via SOURCE_DATE_EPOCH, skips redundant layer uploads when the target manifest already exists.
  • File-based apps: #:include lets you split scripts across multiple files; Native AOT build-output reuse speeds repeated runs.
  • Solution filters: dotnet sln can now create and edit .slnf files from the CLI.

Library Highlights

  • LINQ FullJoin — finally in the box, alongside tuple-returning Join and GroupJoin across Enumerable, Queryable, and AsyncEnumerable.
  • Zstandard compressionSystem.IO.Compression now includes Zstd natively; no third-party package required.
  • Async validationAsyncValidationAttribute and IAsyncValidatableObject in DataAnnotations for validation logic involving async I/O.
  • Zero-copy streamsReadOnlyMemoryStream, WritableMemoryStream, and StringStream wrap in-memory data without allocating.
  • Decimal floating-pointDecimal32, Decimal64, and Decimal128 (IEEE 754) for financial and scientific workloads.

What to Do Now

Download .NET 11 RC1 and try it on a non-critical workload. Enable C# 15 union types on a result-type pattern you’ve been faking with tuples or OneOf, and check what Runtime Async does to your profiler output. GA is November — the window to shape the final release with real-world feedback is open now.

Full release notes are on the .NET Blog and the Microsoft Learn overview. If you’re planning to use union types in production code, the C# 15 union types deep dive on the .NET Blog is required reading.

ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to cover latest tech news, controversies, and summarizing them into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *

    More in:News