Skip to content

Commit

Permalink
What's New - .NET 10 Preview 1 (dotnet#44878)
Browse files Browse the repository at this point in the history
* initial commit

* additions

* couple more tweaks

* whoops

* Apply suggestions from code review

Co-authored-by: Genevieve Warren <[email protected]>

* Update .openpublishing.redirection.core.json

Co-authored-by: Genevieve Warren <[email protected]>

* Added SDK

* whoopsie

* Added some more content

* more links

* lint

* Apply suggestions from code review

Thank you @gewarren!

Co-authored-by: Genevieve Warren <[email protected]>

* tweaks

* Apply suggestions from code review

Co-authored-by: Genevieve Warren <[email protected]>

* updates

* Remove snippets for now

* Overview updates

* Copilot broke my lint

* fix warning

* download link

* metadata

* Added project

* fix suggestion

* Aspire

* Apply suggestions from code review

Co-authored-by: Genevieve Warren <[email protected]>

* feedback

* fix overview

* Apply suggestions from code review

Co-authored-by: Rich Lander <[email protected]>

* whoops

* MAUI

* winforms

* links

* .net 9

* build them snippets

* Temporarily remove snippets

---------

Co-authored-by: Genevieve Warren <[email protected]>
Co-authored-by: Rich Lander <[email protected]>
  • Loading branch information
3 people authored Feb 25, 2025
1 parent 04a7d1a commit 88917d8
Show file tree
Hide file tree
Showing 12 changed files with 522 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .openpublishing.redirection.core.json
Original file line number Diff line number Diff line change
Expand Up @@ -1327,7 +1327,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
197 changes: 197 additions & 0 deletions docs/core/whats-new/dotnet-10/libraries.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
---
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.

There is some risk to using the `Find` method for finding SHA-2-256 ("SHA256") and SHA-3-256 thumbprints since these hash algorithms have the same lengths.

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="snippet1"::: -->

```csharp
StringComparer numericStringComparer = StringComparer.Create(CultureInfo.CurrentCulture, CompareOptions.NumericOrdering);

Console.WriteLine(numericStringComparer.Equals("02", "2"));
// Output: True
foreach (string os in new[] { "Windows 8", "Windows 10", "Windows 11" }.Order(numericStringComparer))
{
Console.WriteLine(os);
}

// Output:
// Windows 8
// Windows 10
// Windows 11
HashSet<string> set = new HashSet<string>(numericStringComparer) { "007" };
Console.WriteLine(set.Contains("7"));
// Output: True
```

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"::: -->

```csharp
// Try to add a new key with value 1.
if (!orderedDictionary.TryAdd(key, 1, out int index))
{
// Key was present, so increment the existing value instead.
int value = orderedDictionary.GetAt(index).Value;
orderedDictionary.SetAt(index, value + 1);
}
```

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"::: -->

```csharp
public static void MakeSelfRef()
{
SelfReference selfRef = new SelfReference();
selfRef.Me = selfRef;

Console.WriteLine(JsonSerializer.Serialize(selfRef, ContextWithPreserveReference.Default.SelfReference));
// Output: {"$id":"1","Me":{"$ref":"1"}}
}

[JsonSourceGenerationOptions(ReferenceHandler = JsonKnownReferenceHandler.Preserve)]
[JsonSerializable(typeof(SelfReference))]
internal partial class ContextWithPreserveReference : JsonSerializerContext
{
}

internal class SelfReference
{
public SelfReference Me { get; set; } = null!;
}
```

## More left-handed matrix transformation methods

.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)
public static Matrix4x4 CreateConstrainedBillboardLeftHanded(Vector3 objectPosition, Vector3 cameraPosition, Vector3 rotateAxis, Vector3 cameraForwardVector, Vector3 objectForwardVector)
}
```
102 changes: 102 additions & 0 deletions docs/core/whats-new/dotnet-10/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
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 10, the successor to [.NET 9](../dotnet-9/overview.md) and 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).

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).

## .NET runtime

The .NET 10 runtime has introduced new features and performance improvements, which have been updated for Preview 1. One of the main focuses for .NET 10 is to reduce the abstraction overhead of popular language features. In order to achieve this goal, the JIT's ability to devirtualize method calls has been expanded to cover array interface methods. This means that the JIT can now optimize code that loops over an array, even if there are virtual calls involved. Additionally, the JIT now has the ability to stack-allocate small, fixed-sized arrays of value types that do not contain GC pointers, further reducing the abstraction penalty of reference types.

Another new feature in .NET 10 is the support for Advanced Vector Extensions (AVX) 10.2 for x64-based processors. This is currently disabled by default as hardware supporting AVX10.2 is not yet available. Once it is available, the new intrinsics in the `System.Runtime.Intrinsics.X86.Avx10v2` class can be tested. These updates and improvements are part of the ongoing efforts to achieve performance parity between different implementations in .NET 10.

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.

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

This release was focused on quality improvements to .NET MAUI, .NET for Android, and .NET for iOS, Mac Catalyst, macOS, and tvOS.

For more information, see [What's new in .NET MAUI in .NET 10](/dotnet/maui/whats-new/dotnet-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](/dotnet/csharp/whats-new/csharp-14).

## Windows Forms

Changes in Windows Forms for .NET 10 include:

- Clipboard-related serialization and deserialization changes.
- Obsoleted Clipboard APIs.
- New Clipboard-related APIs.

For more information, see [What's new in Windows Forms for .NET 10](/dotnet/desktop/winforms/whats-new/net100).

## 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)
Loading

0 comments on commit 88917d8

Please sign in to comment.