Bemærk
Adgang til denne side kræver godkendelse. Du kan prøve at logge på eller ændre mapper.
Adgang til denne side kræver godkendelse. Du kan prøve at ændre mapper.
This article describes new features in the .NET libraries for .NET 11. It was last updated for Preview 3.
String and character enhancements
.NET 11 introduces significant enhancements to string and character manipulation APIs, making it easier to work with Unicode characters and runes.
Rune support in String methods
The String class now includes methods that accept Rune parameters, enabling you to search, replace, and manipulate strings using Unicode scalar values directly. These new methods include:
Contains- Check if a string contains a specific rune: String.Contains(Rune) and String.Contains(Rune, StringComparison).StartsWithandEndsWith- Check if a string starts or ends with a specific rune: String.StartsWith(Rune), String.StartsWith(Rune, StringComparison), String.EndsWith(Rune), and String.EndsWith(Rune, StringComparison).IndexOfandLastIndexOf- Find the position of a rune in a string: String.IndexOf(Rune), String.IndexOf(Rune, StringComparison), String.LastIndexOf(Rune), and String.LastIndexOf(Rune, StringComparison).Replace- Replace occurrences of one rune with another: String.Replace(Rune, Rune).Split- Split a string using a rune as the separator: String.Split(Rune, StringSplitOptions) and String.Split(Rune, Int32, StringSplitOptions).Trim,TrimStart, andTrimEnd- Trim runes from strings: String.Trim(Rune), String.TrimStart(Rune), and String.TrimEnd(Rune).
Many of these methods include overloads that accept a StringComparison parameter for culture-aware comparisons.
Char.Equals with StringComparison
The Char struct now includes an Char.Equals(Char, StringComparison) method that accepts a StringComparison parameter, allowing you to compare characters using culture-aware or ordinal comparisons.
Rune support in TextInfo
The TextInfo class now provides TextInfo.ToLower(Rune) and TextInfo.ToUpper(Rune) methods that accept Rune parameters, enabling you to perform case conversions on individual Unicode scalar values.
Base64 encoding improvements
.NET 11 adds new APIs and overloads to the existing Base64 type, providing comprehensive support for Base64 encoding and decoding. These additions offer improved performance and flexibility compared to existing methods.
New Base64 APIs
The new APIs support encoding and decoding operations with various input and output formats:
- Encoding to chars: EncodeToChars and EncodeToString
- Encoding to UTF-8: EncodeToUtf8
- Decoding from chars: DecodeFromChars
- Decoding from UTF-8: DecodeFromUtf8
These methods provide both high-level convenience methods (that allocate and return arrays or strings) and low-level span-based methods (for zero-allocation scenarios).
Compression enhancements
.NET 11 includes several improvements to compression APIs.
ZIP archive entry access modes
The ZipArchiveEntry class now supports opening entries with specific file access modes through new overloads: ZipArchiveEntry.Open(FileAccess) and ZipArchiveEntry.OpenAsync(FileAccess, CancellationToken). These overloads accept a FileAccess parameter and allow you to open ZIP entries for read, write, or read-write access.
Additionally, a new CompressionMethod property exposes the compression method used for an entry through the ZipCompressionMethod enum, which includes values for Stored, Deflate, and Deflate64.
ZIP CRC32 validation
Starting in Preview 3, ZipArchive validates the CRC32 checksum when reading ZIP entries. Corrupted or truncated archives that previously passed without error now throw InvalidDataException, helping you detect data integrity issues early.
DeflateStream and GZipStream behavior change
Starting in .NET 11, DeflateStream and GZipStream always write format headers and footers to the output stream, even when no data is written. This ensures the output is a valid compressed stream according to the Deflate and GZip specifications.
Previously, these streams didn't produce any output if no data was written, resulting in an empty output stream. This change ensures compatibility with tools that expect properly formatted compressed streams.
For more information, see DeflateStream and GZipStream write headers and footers for empty payload.
BFloat16 support in BitConverter
The BitConverter class now includes methods for converting between BFloat16 values and byte arrays or bit representations. These new methods include:
- BitConverter.GetBytes(BFloat16) - Convert a BFloat16 value to a byte array.
- BitConverter.ToBFloat16(Byte[], Int32) and BitConverter.ToBFloat16(ReadOnlySpan<Byte>) - Convert a byte array to a BFloat16 value.
- BitConverter.BFloat16ToInt16Bits(BFloat16), BitConverter.BFloat16ToUInt16Bits(BFloat16), BitConverter.Int16BitsToBFloat16(Int16), and BitConverter.UInt16BitsToBFloat16(UInt16) - Methods for converting between BFloat16 and its bit representation as
shortorushort.
BFloat16 (Brain Floating Point) is a 16-bit floating-point format that's commonly used in machine learning and scientific computing.
Collections improvements
BitArray.PopCount
The BitArray class now includes a BitArray.PopCount() method that returns the number of bits set to true in the array. This provides an efficient way to count set bits without manually iterating through the array.
IReadOnlySet support in JSON serialization
The JsonMetadataServices class now includes a JsonMetadataServices.CreateIReadOnlySetInfo method, enabling JSON serialization support for IReadOnlySet<T> collections.
URI data scheme constant
A new Uri.UriSchemeData constant has been added, representing the data: URI scheme. This constant provides a standardized way to reference data URIs.
StringSyntax attribute enhancements
The StringSyntaxAttribute class now includes constants for common programming languages:
- CSharp - Indicates C# syntax.
- FSharp - Indicates F# syntax.
- VisualBasic - Indicates Visual Basic syntax.
These constants can be used with the StringSyntax attribute to provide better tooling support for string literals containing code in these languages.
System.Text.Json improvements
Generic type info retrieval
A common pattern when working with System.Text.Json type metadata is to retrieve a JsonTypeInfo<T> from JsonSerializerOptions.
Previously, you had to manually downcast from the non-generic GetTypeInfo(Type) method.
New generic JsonSerializerOptions.GetTypeInfo<T>() and JsonSerializerOptions.TryGetTypeInfo<T>(JsonTypeInfo<T>) methods return strongly typed metadata directly, eliminating the cast.
JsonSerializerOptions options = new(JsonSerializerDefaults.Web);
options.MakeReadOnly();
// Before: manual downcast required
JsonTypeInfo<MyRecord> info1 = (JsonTypeInfo<MyRecord>)options.GetTypeInfo(typeof(MyRecord));
// After: generic method returns the right type directly
JsonTypeInfo<MyRecord> info2 = options.GetTypeInfo<MyRecord>();
// TryGetTypeInfo variant for cases where the type may not be registered
if (options.TryGetTypeInfo<MyRecord>(out JsonTypeInfo<MyRecord>? typeInfo))
{
// Use typeInfo
_ = typeInfo;
}
This is particularly useful when working with source generation, NativeAOT, and polymorphic serialization scenarios where type metadata access is common.
Naming and ignore defaults
Preview 3 expands the naming and ignore options available in System.Text.Json:
JsonNamingPolicy.PascalCase: A new built-in naming policy that converts property names to PascalCase. It joins the existing camelCase, snake_case, and kebab-case policies.- Per-member naming policy: The new
[JsonNamingPolicy]attribute lets you override the naming policy on individual properties or fields, giving you fine-grained control without a custom converter. - Type-level ignore conditions: Applying
[JsonIgnore(Condition = ...)]at the class or struct level sets the default ignore behavior for all members, so you no longer need to repeat the attribute on every nullable property.
// Type-level JsonIgnore: all members use WhenWritingNull by default
// Per-member JsonNamingPolicy: EventName uses camelCase even though the
// serializer options use PascalCase
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.PascalCase
};
var data = new EventData { EventName = "Launch", Notes = null };
string json = JsonSerializer.Serialize(data, options);
Console.WriteLine(json);
// {"eventName":"Launch"} -- Notes omitted (null), EventName camel-cased
Zstandard compression
The Zstandard compression APIs are now part of the System.IO.Compression namespace, alongside DeflateStream, GZipStream, and BrotliStream. If you referenced the earlier preview package, remove the separate package reference:
-<PackageReference Include="System.IO.Compression.Zstandard" />
The API surface is otherwise unchanged.
Tar archive format selection
New overloads on CreateFromDirectory and CreateFromDirectoryAsync accept a TarEntryFormat parameter, giving you direct control over the archive format. Previously, CreateFromDirectory always produced Pax archives. The new overloads support all four tar formats—Pax, Ustar, GNU, and V7—for compatibility with specific tools and environments.
// Create a GNU format tar archive for Linux compatibility
TarFile.CreateFromDirectory("/source/dir", "/dest/archive.tar",
includeBaseDirectory: true, format: TarEntryFormat.Gnu);
// Create a Ustar format archive for broader compatibility
using Stream outputStream = File.OpenWrite("/dest/ustar.tar");
TarFile.CreateFromDirectory("/source/dir", outputStream,
includeBaseDirectory: false, format: TarEntryFormat.Ustar);
// Async version
CancellationToken cancellationToken = CancellationToken.None;
await TarFile.CreateFromDirectoryAsync("/source/dir", "/dest/archive.tar",
includeBaseDirectory: true, format: TarEntryFormat.Pax,
cancellationToken: cancellationToken);
Numerics improvements
Matrix4x4 performance
Matrix4x4.GetDeterminant() now uses an SSE-vectorized implementation, improving performance by approximately 15%.
Low-level I/O improvements
SafeFileHandle pipe support
SafeFileHandle gains two new members in Preview 3:
Typeproperty: Reports whether a handle represents a file, pipe, socket, directory, or other OS object, without requiring platform-specific code.CreateAnonymousPipemethod: Creates a pair of connected anonymous pipe handles with independent async behavior for each end.
SafeFileHandle.CreateAnonymousPipe(
out SafeFileHandle readEnd,
out SafeFileHandle writeEnd,
asyncRead: true,
asyncWrite: false);
using (readEnd)
using (writeEnd)
{
// SafeFileHandle.Type reports the kind of OS object the handle refers to
Console.WriteLine(readEnd.Type); // Pipe
Console.WriteLine(writeEnd.Type); // Pipe
}
RandomAccess pipe support
RandomAccess.Read and RandomAccess.Write now work with non-seekable handles such as pipes, in addition to regular file handles.
On Windows, Process now uses overlapped I/O for redirected stdout/stderr, which reduces thread-pool blocking in process-heavy applications.
Regular expression improvements
AnyNewLine option
A new RegexOptions flag, AnyNewLine, makes ^, $, and . treat the full set of Unicode newline characters as line terminators—not just \n. This helps when parsing text that mixes Windows (\r\n), Unix (\n), and Unicode-specific (\u0085, \u2028, \u2029) line endings.
string text = "line1\r\nline2\u0085line3\u2028line4";
// RegexOptions.AnyNewLine makes ^, $, and . treat all Unicode newline
// sequences as line terminators, not just \n.
MatchCollection matches = Regex.Matches(
text,
@"^line\d$",
RegexOptions.Multiline | RegexOptions.AnyNewLine);
Console.WriteLine(matches.Count); // 4