Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What's New - .NET 10 Preview 1 #44878

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion .openpublishing.redirection.core.json
Original file line number Diff line number Diff line change
Expand Up @@ -1331,7 +1331,7 @@
},
{
"source_path_from_root": "/docs/core/whats-new/index.md",
"redirect_url": "/dotnet/core/whats-new/dotnet-9/overview",
"redirect_url": "/dotnet/core/whats-new/dotnet-10/overview",
"ms.custom": "updateeachrelease"
},
{
Expand Down
144 changes: 144 additions & 0 deletions docs/core/whats-new/dotnet-10/libraries.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
---
title: What's new in .NET libraries for .NET 10
description: Learn about the new .NET libraries features introduced in .NET 10.
titleSuffix: ""
ms.date: 02/20/2025
ms.topic: whats-new
ai-usage: ai-assisted
---

# What's new in .NET libraries for .NET 10

This article describes new features in the .NET libraries for .NET 10. It has been updated for Preview 1.

## Find certificates by thumbprints other than SHA-1

Finding certificates uniquely by thumbprint is a fairly common operation, but the <xref:System.Security.Cryptography.X509Certificates.X509Certificate2Collection.Find(System.Security.Cryptography.X509Certificates.X509FindType,System.Object,System.Boolean)?displayProperty=nameWithType> method (for the <xref:System.Security.Cryptography.X509Certificates.X509FindType.FindByThumbprint> mode) only searches for the SHA-1 Thumbprint value.

Since SHA-2-256 ("SHA256") and SHA-3-256 have the same lengths, it doesn't make sense to implement the `Find` method to find any *vaguely* matching thumbprints.

Instead, .NET 10 introduces a new method that accepts the name of the hash algorithm to use for matching.

```csharp
X509Certificate2Collection coll = store.Certificates.FindByThumbprint(HashAlgorithmName.SHA256, thumbprint);
Debug.Assert(coll.Count < 2, "Collection has too many matches, has SHA-2 been broken?");
return coll.SingleOrDefault();
```

## Find PEM-encoded Data in ASCII/UTF-8

The PEM encoding (originally "Privacy Enhanced Mail", but now used widely outside of email) is defined for "text", which means that the <xref:System.Security.Cryptography.PemEncoding> class was designed to run on <xref:System.String> and `ReadOnlySpan<char>`. However, it's quite common (especially on Linux) to have something like a certificate written in a file that uses the ASCII (string) encoding. Historically, that meant you needed to open the file and convert the bytes to chars (or a string) before you could use `PemEncoding`.

Taking advantage of the fact that PEM is only defined for 7-bit ASCII characters, and that 7-bit ASCII has a perfect overlap with single-byte UTF-8 values, you can now skip the UTF-8/ASCII-to-char conversion and read the file directly.

```diff
byte[] fileContents = File.ReadAllBytes(path);
-char[] text = Encoding.ASCII.GetString(fileContents);
-PemFields pemFields = PemEncoding.Find(text);
+PemFields pemFields = PemEncoding.FindUtf8(fileContents);

-byte[] contents = Base64.DecodeFromChars(text.AsSpan()[pemFields.Base64Data]);
+byte[] contents = Base64.DecodeFromUtf8(fileContents.AsSpan()[pemFields.Base64Data]);
```

## New method overloads in ISOWeek for DateOnly type

The <xref:System.Globalization.ISOWeek> class was originally designed to work exclusively with <xref:System.DateTime>, as it was introduced before the <xref:System.DateOnly> type existed. Now that `DateOnly` is available, it makes sense for `ISOWeek` to support it as well.

```csharp
public static class ISOWeek
{
// New overloads
public static int GetWeekOfYear(DateOnly date);
public static int GetYear(DateOnly date);
public static DateOnly ToDateOnly(int year, int week, DayOfWeek dayOfWeek);
}
```

## String normalization APIs to work with span of characters

Unicode string normalization has been supported for a long time, but existing APIs have only worked with the string type. This means that callers with data stored in different forms, such as character arrays or spans, must allocate a new string to use these APIs. Additionally, APIs that return a normalized string always allocate a new string to represent the normalized output.

.NET 10 introduces new APIs that work with spans of characters, expanding normalization beyond string types and helping to avoid unnecessary allocations.

```csharp
public static class StringNormalizationExtensions
{
public static int GetNormalizedLength(this ReadOnlySpan<char> source, NormalizationForm normalizationForm = NormalizationForm.FormC);
public static bool IsNormalized(this ReadOnlySpan<char> source, NormalizationForm normalizationForm = NormalizationForm.FormC);
public static bool TryNormalize(this ReadOnlySpan<char> source, Span<char> destination, out int charsWritten, NormalizationForm normalizationForm = NormalizationForm.FormC);
}
```

## Numeric ordering for string comparison

Numerical string comparison is a highly requested feature for comparing strings numerically instead of lexicographically. For example, `2` is less than `10`, so `"2"` should appear before `"10"` when ordered numerically. Similarly, `"2"` and `"02"` are equal numerically. With the new `CompareOptions.NumericOrdering` <!--xref:System.Globalization.CompareOptions.NumericOrdering--> option, it's now possible to do these types of comparisons:

:::code language="csharp" source="../snippets/dotnet-10/csharp/snippets.cs" id="snippet3":::

Note that this option is not valid for the following index-based string operations: `IndexOf`, `LastIndexOf`, `StartsWith`, `EndsWith`, `IsPrefix`, and `IsSuffix`.

## New `TimeSpan.FromMilliseconds` overload with single parameter

The <xref:System.TimeSpan.FromMilliseconds(System.Int64,System.Int64)?displayProperty=nameWithType> method was introduced previously without adding an overload that takes a single parameter.

Although this works since the second parameter is optional, it causes a compilation error when used in a LINQ expression like:

```csharp
Expression<Action> a = () => TimeSpan.FromMilliseconds(1000);
```

The issue arises because LINQ expressions cannot handle optional parameters. To address this, .NET 10 introduces an overload takes a single parameter and modifying the existing method to make the second parameter mandatory:

```csharp
public readonly struct TimeSpan
{
public static TimeSpan FromMilliseconds(long milliseconds, long microseconds); // Second parameter is no longer optional
public static TimeSpan FromMilliseconds(long milliseconds); // New overload
}
```

## ZipArchive performance and memory improvements

.NET 10 improves the performance and memory usage of <xref:System.IO.Compression.ZipArchive>.

First, the way entries are written to a `ZipArchive` when in `Update` mode has been optimized. Previously, all <xref:System.IO.Compression.ZipArchiveEntry> instances were loaded into memory and rewritten, which could lead to high memory usage and performance bottlenecks. The optimization reduces memory usage and improves performance by avoiding the need to load all entries into memory. Details are provided in [dotnet/runtime #102704](https://github.com/dotnet/runtime/pull/102704#issue-2317941700).

Second, the extraction of <xref:System.IO.Compression.ZipArchive> entries is now parallelized, and internal data structures are optimized for better memory usage. These improvements address issues related to performance bottlenecks and high memory usage, making `ZipArchive` more efficient and faster, especially when dealing with large archives. Details are provided [dotnet/runtime #103153](https://github.com/dotnet/runtime/pull/103153#issue-2339713028).

## Additional `TryAdd` and `TryGetValue` overloads for `OrderedDictionary<TKey, TValue>`

<xref:System.Collections.Generic.OrderedDictionary`2> provides `TryAdd` and `TryGetValue` for addition and retrieval like any other `IDictionary<TKey, TValue>` implementation. However, there are scenarios where you might want to perform additional operations, so new overloads have been added that return an index to the entry:

```csharp
public class OrderedDictionary<TKey, TValue>
{
// New overloads
public bool TryAdd(TKey key, TValue value, out int index);
public bool TryGetValue(TKey key, out TValue value, out int index);
}
```

This index can then be used with <xref:System.Collections.Generic.OrderedDictionary`2.GetAt*>/<xref:System.Collections.Generic.OrderedDictionary`2.SetAt*> for fast access to the entry. An example usage of the new `TryAdd` overload is to add or update a key/value pair in the ordered dictionary:

:::code language="csharp" source="../snippets/dotnet-10/csharp/snippets.cs" id="snippet2":::

This new API is already used in <xref:System.Json.JsonObject> and improves the performance of updating properties by 10-20%.

## Allow specifying ReferenceHandler in `JsonSourceGenerationOptions`

When using source generators for JSON serialization, the generated context will throw when cycles are serialized or deserialized. This behavior can now be customized by specifying the <xref:System.Text.Json.Serialization.ReferenceHandler> in the <xref:System.Text.Json.Serialization.JsonSourceGenerationOptionsAttribute>. Here is an example using `JsonKnownReferenceHandler.Preserve`:

:::code language="csharp" source="../snippets/dotnet-10/csharp/snippets.cs" id="snippet3":::

## More left-handed matrix transformation methods
CamSoper marked this conversation as resolved.
Show resolved Hide resolved

.NET 10 adds the remaining APIs for creating left-handed transformation matrices for billboard and constrained-billboard matrices. You can use these methods like their existing right-handed counterparts [add xrefs to the existing counterparts] when using a left-handed coordinate system instead.

```csharp
public partial struct Matrix4x4
{
public static Matrix4x4 CreateBillboardLeftHanded(Vector3 objectPosition, Vector3 cameraPosition, Vector3 cameraUpVector, Vector3 cameraForwardVector)
## More left-handed matrix transformation methods
}
```
96 changes: 96 additions & 0 deletions docs/core/whats-new/dotnet-10/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
---
title: What's new in .NET 10
description: Learn about the new features introduced in .NET 10 for the runtime, libraries, and SDK. Also find links to what's new in other areas, such as ASP.NET Core.
titleSuffix: ""
ms.date: 02/20/2025
ms.topic: whats-new
ai-usage: ai-assisted
---

# What's new in .NET 10

Learn about the new features in .NET 10 and find links to further documentation. This page has been updated for Preview 1.

## .NET runtime

.NET 10, the successor to [.NET 9](../dotnet-9/overview.md), has a special focus on cloud-native apps and performance. It will be [supported for 3 years](https://dotnet.microsoft.com/platform/support/policy/dotnet-core) as a long-term support (LTS) release. You can [download .NET 10 here](https://get.dot.net/10).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't specific to the runtime, so don't think it belongs in this section.


Your feedback is important and appreciated. We've created a discussion on [GitHub](https://github.com/dotnet/core/discussions/categories/news) for your questions and comments.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Your feedback is important and appreciated. We've created a discussion on [GitHub](https://github.com/dotnet/core/discussions/categories/news) for your questions and comments.
Your feedback is important and appreciated. If you have questions or comments, please use the discussion on [GitHub](https://github.com/dotnet/core/discussions/categories/news).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But also pull it out of the runtime section.


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

## .NET libraries

The .NET 10 libraries introduce several new features and improvements. A new method `FindByThumbprint` allows finding certificates by thumbprints using hash algorithms other than SHA-1. Additionally, support has been added for reading PEM-encoded data directly from ASCII encoded files. The <xref:System.Globalization.ISOWeek> class now includes new method overloads to support the <xref:System.DateOnly> type. Unicode string normalization APIs have been enhanced to work with spans of characters, and a new `CompareOptions.NumericOrdering` option has been introduced for numerical string comparison.

Additionally, a new <xref:System.TimeSpan.FromMilliseconds*?displayProperty=nameWithType> overload that takes a single parameter has been added. The performance and memory usage of [ZipArchive](xref:System.IO.Compression.ZipArchive) have been improved. New `TryAdd` and `TryGetValue` overloads for <xref:System.Collections.Generic.OrderedDictionary`2?displayProperty=nameWithType> now return an index to the entry. JSON serialization has been enhanced by allowing the specification of <xref:System.Text.Json.Serialization.ReferenceHandler> in <xref:System.Text.Json.Serialization.JsonSourceGenerationOptionsAttribute>. Lastly, new APIs have been introduced for creating left-handed transformation matrices for billboard and constrained-billboard matrices.

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

## .NET SDK

The .NET 10 SDK introduces following new features and enhancements:

- [Pruning of Framework-provided Package References](sdk.md#pruning-of-framework-provided-package-references)

For more information, see [What's new in the SDK for .NET 10](sdk.md).

## .NET Aspire

.NET Aspire releases version 9.1, which focuses on quality of life fixes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.NET Aspire releases version 9.1, which focuses on quality of life fixes.
.NET Aspire releases version 9.1, which focuses on quality-of-life fixes.


For more information, see [.NET Aspire — what's new?](/dotnet/aspire/whats-new/).

## ASP.NET Core

Changes in ASP.NET Core 10.0 include:

- Blazor: Added new features for Blazor, including the QuickGrid RowClass parameter and Blazor script serving as a static web asset.
- SignalR: Added new features for SignalR.
- Minimal APIs: Added new features for minimal APIs.
- OpenAPI: Added support for generating OpenAPI version 3.1 documents and serving the generated OpenAPI document in YAML format.
- Authentication and authorization: Added new features for authentication and authorization.
- Miscellaneous: Added better support for testing apps with top-level statements and a new helper method for detecting local URLs.

For more information, see [What's new in ASP.NET Core for .NET 10](/aspnet/core/release-notes/aspnetcore-10.0).

## .NET MAUI

<!-- TODO - Add a brief overview of the new features in .NET MAUI for .NET 10. -->

## EF Core

Changes for EF Core 10 include:

- LINQ and SQL translation enhancements.
- ExecuteUpdateAsync now accepts a regular, non-expression lambda.

For more information, see [What's new in EF Core for .NET 10](/ef/core/what-is-new/ef-core-10.0/whatsnew).

## C# 14

C# 14 introduces several new features and enhancements to improve developer productivity and code quality. Some of the key updates include:

- `nameof` in unbound generics.
- Implicit span conversions.
- `field` backed properties.
- Modifiers on simple lambda parameters.
- Experimental feature - String literals in data section.

For more information, see [What's new in C# 14](https://github.com/dotnet/core/blob/dotnet10p1/release-notes/10.0/preview/preview1/csharp.md).

## Windows Forms

Changes in Windows Forms for .NET 10 include:

- Clipboard related serialization and deserialization changes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Clipboard related serialization and deserialization changes.
- Clipboard-related serialization and deserialization changes.

- Obsoleted Clipboard APIs.
- New Clipboard related APIs.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- New Clipboard related APIs.
- New Clipboard-related APIs.


For more information, see [What's new in Windows Forms for .NET 10](https://github.com/dotnet/core/blob/dotnet10p1/release-notes/10.0/preview/preview1/winforms.md).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The link should be updated once Andy publishes.


## See also

- [.NET 10 Preview 1 container image updates](https://github.com/dotnet/core/blob/dotnet10p1/release-notes/10.0/preview/preview1/containers.md)
- [F# updates in .NET 10 Preview 1](https://github.com/dotnet/core/blob/dotnet10p1/release-notes/10.0/preview/preview1/fsharp.md)
- [Visual Basic updates in .NET 10 Preview 1](https://github.com/dotnet/core/blob/dotnet10p1/release-notes/10.0/preview/preview1/visualbasic.md)
79 changes: 79 additions & 0 deletions docs/core/whats-new/dotnet-10/runtime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
title: What's new in .NET 10 runtime
description: Learn about the new .NET features introduced in the .NET 10 runtime.
titleSuffix: ""
ms.date: 02/20/2025
ms.topic: whats-new
ai-usage: ai-assisted
---
# What's new in the .NET 10 runtime

This article describes new features and performance improvements in the .NET runtime for .NET 10. It has been updated for Preview 1.

## Array interface method devirtualization

One of the code generation team's [focus areas](https://github.com/dotnet/runtime/issues/108988) for .NET 10 is to reduce the abstraction overhead of popular language features. In pursuit of this goal, the JIT's ability to devirtualize method calls has been expanded to cover array interface methods.

Consider the typical approach of looping over an array:

```csharp
static int Sum(int[] array)
{
int sum = 0;
for (int i = 0; i < array.Length; i++)
{
sum += array[i];
}
return sum;
}
```

This code shape is easy for the JIT to optimize, mainly because there aren't any virtual calls to reason about. Instead, the JIT can focus on removing bounds checks on the array access and applying the [loop optimizations that were added in .NET 9](https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-9/). The following example adds some virtual calls:

```csharp
CamSoper marked this conversation as resolved.
Show resolved Hide resolved
static int Sum(int[] array)
{
int sum = 0;
IEnumerable<int> temp = array;

foreach (var num in temp)
{
sum += num;
}
return sum;
}
```

The type of the underlying collection is clear, and the JIT should be able to transform this snippet into the first one. However, array interfaces are implemented differently from "normal" interfaces, such that the JIT does not know how to devirtualize them. This means the enumerator calls in the `for-each` loop remain virtual, blocking multiple optimizations such as inlining and stack allocation.

Starting in .NET 10, the JIT can devirtualize and inline array interface methods. This is the first of many steps to achieve performance parity between the implementations, as detailed in the [.NET 10 de-abstraction plans](https://github.com/dotnet/runtime/issues/108913).

## Stack allocation of arrays of value types

In .NET 9, the JIT gained the ability to allocate objects on the stack, when the object is guaranteed to not outlive its parent method. Not only does stack allocation reduce the number of objects the GC has to track, but it also unlocks other optimizations. For example, after an object has been stack-allocated, the JIT can consider replacing it entirely with its scalar values. Because of this, stack allocation is key to reducing the abstraction penalty of reference types.

In .NET 10, the JIT now stack-allocates small, fixed-sized arrays of value types that don't contain GC pointers when it can make the same lifetime guarantees described previously. Consider the following example:

```csharp
static void Sum()
CamSoper marked this conversation as resolved.
Show resolved Hide resolved
{
int[] numbers = {1, 2, 3};
int sum = 0;

for (int i = 0; i < numbers.Length; i++)
{
sum += numbers[i];
}

Console.WriteLine(sum);
}

```

Because the JIT knows `numbers` is an array of only three integers at compile time, and it doesn't outlive a call to `Sum`, it allocates it on the stack.

## AVX10.2 support

.NET 10 introduces support for the Advanced Vector Extensions (AVX) 10.2 for x64-based processors. The new intrinsics available in the `System.Runtime.Intrinsics.X86.Avx10v2` <!--xref:System.Runtime.Intrinsics.X86.Avx10v2--> class can be tested once capable hardware is available.

Because AVX10.2-enabled hardware is not yet available, the JIT's support for AVX10.2 is currently disabled by default.
Loading
Loading