Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 151 additions & 3 deletions docs/core/whats-new/dotnet-11/libraries.md

Large diffs are not rendered by default.

12 changes: 9 additions & 3 deletions docs/core/whats-new/dotnet-11/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
title: What's new in .NET 11
description: Learn about the new features introduced in .NET 11 for the runtime, libraries, and SDK. Also find links to what's new in other areas, such as ASP.NET Core.
titleSuffix: ""
ms.date: 05/12/2026
ms.date: 06/09/2026
ai-usage: ai-assisted
ms.update-cycle: 3650-days
---

# What's new in .NET 11

This article describes new features in .NET 11. It was last updated for Preview 4.
This article describes new features in .NET 11. It was last updated for Preview 5.

.NET 11 is currently in preview. The final release is expected in November 2026. You can [download .NET 11 here](https://dotnet.microsoft.com/download/dotnet/11.0).

Expand All @@ -29,13 +29,19 @@ The .NET 11 libraries include new APIs for:

- <xref:System.Diagnostics.Process> expansion with run-and-capture helpers, fire-and-forget launches, `SafeProcessHandle` lifecycle methods, and tighter handle control.
- Compression, including improved Base64 APIs, new methods for ZIP archive entries, Zstandard compression in <xref:System.IO.Compression?displayProperty=fullName>, and CRC32 validation when reading ZIP entries.
- System.Text.Json improvements, including generic type info retrieval, <xref:System.Text.Json.JsonNamingPolicy.PascalCase?displayProperty=nameWithType>, per-member naming policy overrides, type-level ignore conditions, F# discriminated union support, and <xref:System.Text.Json.Utf8JsonWriter.Reset*?displayProperty=nameWithType> with options.
- System.Text.Json improvements, including generic type info retrieval, <xref:System.Text.Json.JsonNamingPolicy.PascalCase?displayProperty=nameWithType>, per-member naming policy overrides, type-level ignore conditions, F# discriminated union support, <xref:System.Text.Json.Utf8JsonWriter.Reset*?displayProperty=nameWithType> with options, and `SerializeAsyncEnumerable` overloads for `PipeWriter` targets and top-level values (NDJSON) output.
- Built-in OpenTelemetry metrics for <xref:Microsoft.Extensions.Caching.Memory.MemoryCache>.
- Discriminated-union scaffolding (`UnionAttribute` and `IUnion`) in <xref:System.Runtime.CompilerServices>.
- Tar archive format selection and GNU sparse format 1.0 support.
- `Console` support for the `FORCE_COLOR` environment variable.
- TLS handshake hardening and certificate-validation alerts on Linux.
- HTTP/2 automatic downgrade for Windows authentication.
- LINQ join improvements, including `FullJoin` and tuple-returning `Join` and `GroupJoin` overloads, across <xref:System.Linq.Enumerable>, <xref:System.Linq.Queryable>, and <xref:System.Linq.AsyncEnumerable>.
- A new <xref:System.Security.Cryptography.X25519DiffieHellman> class for X25519 key exchange.
- Generic overloads on <xref:System.Random> — `NextInteger<T>` and `NextBinaryFloat<T>` — that work with any numeric generic type.
- <xref:System.Collections.Generic.EqualityComparer`1.Create*?displayProperty=nameWithType> factory method that creates a comparer from a key selector.
- <xref:System.Net.Quic.QuicStream.Priority?displayProperty=nameWithType> for HTTP/3 stream prioritization.
- Video MIME type constants in <xref:System.Net.Mime.MediaTypeNames.Video>.

For more information, see [What's new in the .NET 11 libraries](libraries.md).

Expand Down
4 changes: 2 additions & 2 deletions docs/core/whats-new/dotnet-11/runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
title: What's new in .NET 11 runtime
description: Learn about the new features introduced in the .NET 11 runtime.
titleSuffix: ""
ms.date: 05/12/2026
ms.date: 06/09/2026
ai-usage: ai-assisted
ms.update-cycle: 3650-days
---

# What's new in the .NET 11 runtime

This article describes new features in the .NET runtime for .NET 11. It was last updated for Preview 4.
This article describes new features in the .NET runtime for .NET 11. It was last updated for Preview 5.

## Updated minimum hardware requirements

Expand Down
4 changes: 2 additions & 2 deletions docs/core/whats-new/dotnet-11/sdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
title: What's new in the SDK and tooling for .NET 11
description: Learn about the new .NET SDK features introduced in .NET 11.
titleSuffix: ""
ms.date: 05/12/2026
ms.date: 06/09/2026
ai-usage: ai-assisted
ms.update-cycle: 3650-days
---

# What's new in the SDK and tooling for .NET 11

This article describes new features and enhancements in the .NET SDK for .NET 11. It was last updated for Preview 4.
This article describes new features and enhancements in the .NET SDK for .NET 11. It was last updated for Preview 5.

## SDK footprint

Expand Down
152 changes: 151 additions & 1 deletion docs/core/whats-new/dotnet-11/snippets/csharp/Libraries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
using System.Formats.Tar;
using System.Globalization;
using System.IO.Compression;
using System.IO.Pipelines;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
using System.Text.RegularExpressions;
using System.Text.Unicode;
using Microsoft.Win32.SafeHandles;

static class LibrariesExamples
public static class LibrariesExamples
{
static async Task ProcessRunAndCaptureExample()
{
Expand Down Expand Up @@ -173,6 +176,153 @@ static void RegexAnyNewLineExample()
Console.WriteLine(matches.Count); // 4
// </RegexAnyNewLine>
}

public static void LinqJoinsExample()
{
// <LinqJoins>
var products = new List<(int Id, string Name, string? Category)>
{
(1, "Laptop", "Electronics"),
(2, "Mouse", "Electronics"),
(3, "Orphan", null), // No matching category
};
var categories = new List<(string Name, string Description)>
{
("Electronics", "Electronic devices"),
("Furniture", "Office furniture"), // No matching product
};

// LeftJoin: all products, matched categories (null if none)
Comment thread
gewarren marked this conversation as resolved.
var leftJoined = products.LeftJoin(
categories,
p => p.Category,
c => c.Name);

foreach (var (product, category) in leftJoined)
Console.WriteLine($"{product.Name}: {category.Description ?? "(none)"}");
// Laptop: Electronic devices
// Mouse: Electronic devices
// Orphan: (none)

// FullJoin: all products and categories, paired where they match
var fullJoined = products.FullJoin(
categories,
p => p.Category,
c => c.Name);

foreach (var (product, category) in fullJoined)
Console.WriteLine(
$"{product.Name ?? "(none)"}: {category.Description ?? "(none)"}");
// Laptop: Electronic devices
// Mouse: Electronic devices
// Orphan: (none)
// (none): Office furniture
// </LinqJoins>
}

static void EqualityComparerCreateExample()
{
// <EqualityComparerCreate>

// Create an equality comparer based on a key selector
var byName = EqualityComparer<(string Name, int Age)>.Create(p => p.Name);

var people = new HashSet<(string Name, int Age)>(byName)
{
("Alice", 30),
("Bob", 25),
("Alice", 40), // Duplicate by name — not added
};
Console.WriteLine(people.Count); // 2
// </EqualityComparerCreate>
}

static void RandomGenericExample()
{
// <RandomGeneric>
// Generate a random integer of any binary integer type
int i = Random.Shared.NextInteger<int>();
long l = Random.Shared.NextInteger<long>(0L, 100L);
byte b = Random.Shared.NextInteger<byte>(maxValue: (byte)10);

// Generate a random floating-point value of any IEEE-754 type
float f = Random.Shared.NextBinaryFloat<float>();
double d = Random.Shared.NextBinaryFloat<double>();
Half h = Random.Shared.NextBinaryFloat<Half>();

Console.WriteLine($"int={i}, long={l}, byte={b}");
Console.WriteLine($"float={f}, double={d}, Half={h}");
// </RandomGeneric>
}

static void StringBuilderMoveChunksExample()
{
// <StringBuilderMoveChunks>
var source = new StringBuilder("Hello, ");
source.Append("World!");

// MoveChunks transfers all content from source to a new StringBuilder.
// After the call, source contains no characters.
StringBuilder dest = StringBuilder.MoveChunks(source);
Console.WriteLine(dest); // Hello, World!
Console.WriteLine(source.Length); // 0
// </StringBuilderMoveChunks>
}

static async Task JsonSerializeAsyncEnumerablePipeExample()
{
// <JsonSerializeAsyncEnumerablePipe>
static async IAsyncEnumerable<int> GenerateNumbers()
{
for (int i = 0; i < 5; i++)
{
yield return i;
await Task.Yield();
}
}

var pipe = new Pipe();

// Write a JSON array: [0,1,2,3,4]
await JsonSerializer.SerializeAsyncEnumerable(
pipe.Writer,
GenerateNumbers());

// Write NDJSON (one value per line): 0\n1\n2\n3\n4\n
await JsonSerializer.SerializeAsyncEnumerable(
pipe.Writer,
GenerateNumbers(),
topLevelValues: true);
// </JsonSerializeAsyncEnumerablePipe>
}

static void X25519KeyExchangeExample()
{
// <X25519KeyExchange>
// Generate key pairs for Alice and Bob
using X25519DiffieHellman alice = X25519DiffieHellman.GenerateKey();
using X25519DiffieHellman bob = X25519DiffieHellman.GenerateKey();

// Each party derives the shared secret using the other's public key
byte[] aliceShared = alice.DeriveRawSecretAgreement(bob);
byte[] bobShared = bob.DeriveRawSecretAgreement(alice);

// Both parties arrive at the same secret
Console.WriteLine(aliceShared.SequenceEqual(bobShared)); // True
// </X25519KeyExchange>
}

static void NullableUnderlyingTypeExample()
{
// <NullableUnderlyingType>
Type nullableIntType = typeof(int?);
Type? underlying = nullableIntType.GetNullableUnderlyingType();
Console.WriteLine(underlying); // System.Int32

Type nonNullable = typeof(int);
Console.WriteLine(nonNullable.GetNullableUnderlyingType() is null); // True
// </NullableUnderlyingType>
}
}

record MyRecord(string Name, int Value);
Expand Down
1 change: 1 addition & 0 deletions docs/core/whats-new/dotnet-11/snippets/csharp/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
LibrariesExamples.LinqJoinsExample();
48 changes: 26 additions & 22 deletions docs/core/whats-new/dotnet-11/snippets/csharp/Runtime.cs
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Diagnostics;

// <RuntimeAsyncStackTrace>
// To enable runtime async, add the following to your .csproj:
// <Features>runtime-async=on</Features>
public class RuntimeExamples
{
public static async Task Run()
{
// <RuntimeAsyncStackTrace>
// To enable runtime async, add the following to your .csproj:
// <Features>runtime-async=on</Features>

await OuterAsync();
await OuterAsync();

static async Task OuterAsync()
{
await Task.CompletedTask;
await MiddleAsync();
}
static async Task OuterAsync()
{
await Task.CompletedTask;
await MiddleAsync();
}

static async Task MiddleAsync()
{
await Task.CompletedTask;
await InnerAsync();
}
static async Task MiddleAsync()
{
await Task.CompletedTask;
await InnerAsync();
}

static async Task InnerAsync()
{
await Task.CompletedTask;
Console.WriteLine(new StackTrace(fNeedFileInfo: true));
static async Task InnerAsync()
{
await Task.CompletedTask;
Console.WriteLine(new StackTrace(fNeedFileInfo: true));
}
// </RuntimeAsyncStackTrace>
}
}
// </RuntimeAsyncStackTrace>
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
// <BodyMembers>
public union OneOrMore<T>(T, IEnumerable<T>) where T : notnull
public record class Meters(double Value);
public record class Feet(double Value);

public union Length(Meters, Feet)
{
public IEnumerable<T> AsEnumerable() => this switch
public double TotalMeters => this switch
{
T single => [single],
IEnumerable<T> multiple => multiple
Meters m => m.Value,
Feet f => f.Value * 0.3048,
_ => throw new InvalidOperationException("The Length has no value."),
};

public Length Add(Length other) => new Meters(TotalMeters + other.TotalMeters);
}
// </BodyMembers>

Expand All @@ -19,11 +25,14 @@ public static void Run()
// <BodyMembersExample>
static void BodyMembersExample()
{
OneOrMore<string> single = "hello";
OneOrMore<string> multiple = new[] { "a", "b", "c" }.AsEnumerable();
Length distance = new Meters(10.0);
Length height = new Feet(3.0);

Console.WriteLine(distance.TotalMeters); // output: 10
Console.WriteLine(height.TotalMeters); // output: 0.9144

Console.WriteLine(string.Join(", ", single.AsEnumerable())); // output: hello
Console.WriteLine(string.Join(", ", multiple.AsEnumerable())); // output: a, b, c
Length total = distance.Add(height);
Console.WriteLine(total.TotalMeters); // output: 10.9144
}
// </BodyMembersExample>
}
Loading
Loading