-
Notifications
You must be signed in to change notification settings - Fork 5.9k
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
.NET 10 Preview 1 breaking changes batch #44625
Open
CamSoper
wants to merge
20
commits into
dotnet:main
Choose a base branch
from
CamSoper:net10-p1-breaking
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+642
−5
Open
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
500bd96
issues/44500
CamSoper a0905d2
Fix for 44500
CamSoper 11191b6
tweaks to 44500, issue 44403
CamSoper 2771ee7
linting
CamSoper dbab525
More 44500
CamSoper df37114
xref
CamSoper d5e8dd9
issue 44282
CamSoper ac4aa25
xref fix
CamSoper e52ff75
issue 43952
CamSoper f07146b
fix linting
CamSoper 65818cd
issue 43885
CamSoper 5703057
issue 43828
CamSoper ccff70b
fix xref
CamSoper 871f312
issue 43303
CamSoper bb151c1
issue 43284
CamSoper 85a79b0
lint
CamSoper 5354c1d
43156
CamSoper bc06024
issue 42558
CamSoper 06ad856
issue 42027
CamSoper f1d5720
build fix
CamSoper File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
docs/core/compatibility/core-libraries/10.0/activity-sampling.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
--- | ||
title: "Breaking change: ActivitySource.CreateActivity and ActivitySource.StartActivity behavior changes" | ||
description: Learn about the .NET 10.0 breaking change in core .NET libraries where ActivitySource.CreateActivity and ActivitySource.StartActivity behavior is modified. | ||
ms.date: 01/30/2025 | ||
--- | ||
# ActivitySource.CreateActivity and ActivitySource.StartActivity behavior change | ||
|
||
The <xref:System.Diagnostics.ActivitySource.CreateActivity*?displayProperty=nameWithType> and <xref:System.Diagnostics.ActivitySource.StartActivity*?displayProperty=nameWithType> APIs only return an `Activity` when there is a registered listener which decides the instance should be created. This is generally known as sampling. | ||
|
||
The <xref:System.Diagnostics.ActivitySamplingResult?displayProperty=nameWithType> enum defines the possible sampling decisions. | ||
|
||
When creating an `Activity` without a parent, `ActivitySamplingResult` drives whether the `Activity` is created and then how the `Recorded` and `IsAllDataRequested` properties are set: | ||
|
||
|ActivitySamplingResult|Activity created|Activity.Recorded|Activity.IsAllDataRequested| | ||
|---|---|---|---| | ||
|None|No||| | ||
|PropagationData|Yes|False|False| | ||
|AllData|Yes|False|True| | ||
|AllDataAndRecorded|Yes|True|True| | ||
|
||
It is also possible to create an `Activity` with a parent. The parent could be in the same process, or it could be a remote parent propagated to the current process. | ||
|
||
## Previous behavior | ||
|
||
When creating an `Activity` as `PropagationData` with a parent marked as `Recorded`: | ||
|
||
|ActivitySamplingResult|Activity created|Activity.Recorded|Activity.IsAllDataRequested| | ||
|---|---|---|---| | ||
|PropagationData|Yes|True|False| | ||
|
||
## New behavior | ||
|
||
When creating an `Activity` as `PropagationData` with a parent marked as `Recorded`: | ||
|
||
|ActivitySamplingResult|Activity created|Activity.Recorded|Activity.IsAllDataRequested| | ||
|---|---|---|---| | ||
|PropagationData|Yes|False|False| | ||
|
||
## Version introduced | ||
|
||
.NET 10 Preview 1 | ||
|
||
## Type of breaking change | ||
|
||
This change is a [behavioral change](../../categories.md#behavioral-change). | ||
|
||
## Reason for change | ||
|
||
The existing behavior does not follow the OpenTelemetry specification. | ||
|
||
## Recommended action | ||
|
||
Users who have implemented `ActivityListener.Sample` directly AND use `ActivitySamplingResult.PropagationData` should verify they are not reliant on the flawed behavior. `Activity.ActivityTraceFlags` may be set to `Recorded` after the `CreateActivity` or `StartActivity` call to restore the previous behavior. | ||
|
||
Users using OpenTelemetry .NET should verify their sampler configuration. The default OpenTelemetry .NET configuration uses a parent-based algorithm which is not impacted. Only users who have customized the sampler should verify the behavior. | ||
|
||
## Affected APIs | ||
|
||
- <xref:System.Diagnostics.ActivitySource.CreateActivity*?displayProperty=fullName> | ||
- <xref:System.Diagnostics.ActivitySource.StartActivity*?displayProperty=fullName> |
50 changes: 50 additions & 0 deletions
50
docs/core/compatibility/core-libraries/10.0/csharp-overload-resolution.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
--- | ||
title: "Breaking change: C# 14 overload resolution with span parameters" | ||
description: Learn about the .NET 10 breaking change in core .NET libraries where overloads with span parameters are applicable in more scenarios. | ||
ms.date: 01/30/2025 | ||
--- | ||
# C# 14 overload resolution with span parameters | ||
|
||
C# 14 introduces new [built-in span conversions and type inference rules](https://github.com/dotnet/csharplang/issues/7905) making overloads with span parameters applicable in more scenarios. | ||
|
||
## Previous behavior | ||
|
||
In C# 13 and earlier, an extension method taking a `ReadOnlySpan<T>` or `Span<T>` receiver is not applicable to a value of type `T[]`. Therefore, only non-span extension methods like the ones from the `System.Linq.Enumerable` class are usually bound inside Expression lambdas. | ||
|
||
## New behavior | ||
|
||
In C# 14 and later, methods with `ReadOnlySpan<T>` or `Span<T>` parameters can participate in type inference or be used as extension methods in more scenarios. This makes span-based methods like the ones from the `System.MemoryExtensions` class bind in more scenarios, including inside Expression lambdas where they will cause runtime exceptions when compiled with interpretation. | ||
|
||
## Version introduced | ||
|
||
.NET 10 Preview 1 | ||
|
||
## Type of breaking change | ||
|
||
This change is a [behavioral change](../../categories.md#behavioral-change). | ||
|
||
## Reason for change | ||
|
||
The C# language feature allows simplified API design and usage (e.g., one ReadOnlySpan extension method can apply to both spans and arrays). | ||
|
||
## Recommended action | ||
|
||
If you need to continue using Expression interpretation, you should make sure the non-span overloads are bound, e.g., by casting arguments to the exact types the method signature takes or calling the extension methods as explicit static invocations: | ||
|
||
```cs | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Linq.Expressions; | ||
|
||
M((array, num) => array.Contains(num)); // fails, binds to MemoryExtensions.Contains | ||
M((array, num) => ((IEnumerable<int>)array).Contains(num)); // ok, binds to Enumerable.Contains | ||
M((array, num) => array.AsEnumerable().Contains(num)); // ok, binds to Enumerable.Contains | ||
M((array, num) => Enumerable.Contains(array, num)); // ok, binds to Enumerable.Contains | ||
|
||
void M(Expression<Func<int[], int, bool>> e) => e.Compile(preferInterpretation: true); | ||
``` | ||
|
||
## Affected APIs | ||
|
||
- <xref:System.Linq.Expressions.Expression`1.Compile*?displayProperty=fullName> |
38 changes: 38 additions & 0 deletions
38
docs/core/compatibility/core-libraries/10.0/generic-math.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
--- | ||
title: "Breaking change: Consistent shift behavior in generic math" | ||
description: Learn about the .NET 10 breaking change in core .NET libraries where shift operations in generic math now have consistent behavior. | ||
ms.date: 01/30/2025 | ||
--- | ||
# Consistent shift behavior in generic math | ||
|
||
This document explains the breaking change in .NET 10 where shift operations in generic math now have consistent behavior across all built-in integer types. | ||
|
||
## Previous behavior | ||
|
||
The behavior when utilizing generic math to perform a shift on a `T` could differ based on the type. In some cases, it would appropriately mask the shift amount by `sizeof(T) - 1` and in other cases, it would do no masking. This meant that "overshifting" (such as shifting a `byte` by 8) could result in different answers than expected. | ||
|
||
## New behavior | ||
|
||
The implementations were updated to mask the shift amount, as appropriate, to ensure consistent behavior across all built-in integer types and with the behavior documented by the <xref:System.Numerics.IShiftOperators`3?displayProperty=nameWithType> interface. | ||
|
||
## Version introduced | ||
|
||
.NET 10 Preview 1 | ||
|
||
## Type of breaking change | ||
|
||
This change is a [behavioral change](../../categories.md#behavioral-change). | ||
|
||
## Reason for change | ||
|
||
The behavior differed from the designed behavior due to a difference in how masking works for small integer types in C#. | ||
|
||
## Recommended action | ||
|
||
Update any code that relies on the previous inconsistent behavior to ensure it works with the new consistent behavior. | ||
|
||
## Affected APIs | ||
|
||
- `operator <<` | ||
- `operator >>` | ||
- `operator >>>` for `byte`, `char`, `sbyte`, `short`, and `ushort` when used via `Generic Math`, which requires a `T` constrained to `where T : IShiftOperators<T, int, T>` or a similar interface. |
62 changes: 62 additions & 0 deletions
62
docs/core/compatibility/core-libraries/10.0/ldap-directorycontrol-parsing.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
--- | ||
title: "Breaking change: LDAP DirectoryControl parsing is now more stringent" | ||
description: Learn about the .NET 10 breaking change in core .NET libraries where LDAP DirectoryControl parsing is now more stringent. | ||
ms.date: 01/30/2025 | ||
--- | ||
|
||
# LDAP DirectoryControl parsing is now more stringent | ||
|
||
Previously, .NET used <xref:System.DirectoryServices.Protocols.BerConverter?displayProperty=nameWithType> to parse the <xref:System.DirectoryServices.Protocols.DirectoryControl?displayProperty=nameWithType> objects it received over the network and to generate the <xref:System.DirectoryServices.Protocols.DirectoryControl?displayProperty=nameWithType> byte arrays it sent; <xref:System.DirectoryServices.Protocols.BerConverter?displayProperty=nameWithType> would use the OS-specific BER parsing functionality. This parsing functionality is now implemented in managed code. | ||
|
||
## Previous behavior | ||
|
||
As a result of using <xref:System.DirectoryServices.Protocols.BerConverter?displayProperty=nameWithType>, the parsing of <xref:System.DirectoryServices.Protocols.DirectoryControl?displayProperty=nameWithType> objects was fairly loose. | ||
|
||
- The ASN.1 tags of each value weren't checked. | ||
- Trailing data after the end of the parsed DirectoryControl was ignored, as was trailing data within an ASN.1 SEQUENCE. | ||
- On Linux, OCTET STRING lengths which extended beyond the end of their parent sequence would return data outside the parent sequence. | ||
- On earlier versions of Windows, a zero-length OCTET STRING would return `null` rather than an empty string. | ||
- When reading the contents of a <xref:System.DirectoryServices.Protocols.DirectoryControl?displayProperty=nameWithType> as a UTF8-encoded string, an invalid UTF8 sequence would not throw an exception. | ||
- When passing an invalid UTF8 string to the constructor of [VlvRequestControl](xref:System.DirectoryServices.Protocols.VlvRequestControl), no exception was thrown. | ||
|
||
While not a breaking change, Windows would always encode ASN.1 tags with a four-byte length while Linux would only use as many bytes for the tag length as it needed. Both representations were valid, but this behavioural difference between platforms is now gone; the Linux behaviour now also appears on Windows. | ||
|
||
## New behavior | ||
|
||
The DirectoryControl parsing is much more stringent, and is now consistent across platforms and versions. | ||
|
||
- ASN.1 tags are now checked. | ||
- Trailing data is no longer permitted. | ||
- The length of OCTET STRINGs and SEQUENCEs is now checked. | ||
- Zero-length OCTET STRINGs will now always return an empty string. | ||
- If the server sends an invalid UTF8 byte sequence, the <xref:System.DirectoryServices.Protocols.DirectoryControl?displayProperty=nameWithType> parsing logic will now throw an exception rather than silently substitute the invalid characters with a known value. | ||
|
||
We also validate errors more thoroughly when calling the VlvRequestControl constructor. Passing a string which cannot be encoded as a UTF8 value will now throw an EncoderFallbackException. | ||
|
||
## Version introduced | ||
|
||
.NET 10 Preview 1 | ||
|
||
## Type of breaking change | ||
|
||
This change is a [behavioral change](../../categories.md#behavioral-change). | ||
|
||
## Reason for change | ||
|
||
RFC/spec. compliance. In the various RFCs and sections of MS-ADTS, the controlValue is specified as the BER encoding of an ASN.1 structure with wording similar to the below (from [RFC2891, section 1.2](https://datatracker.ietf.org/doc/html/rfc2891#section-1.2)): | ||
|
||
> The controlType is set to "1.2.840.113556.1.4.474". The criticality is FALSE (MAY be absent). The controlValue is an OCTET STRING, whose value is the BER encoding of a value of the following SEQUENCE: | ||
|
||
This precludes trailing data. It also rules out BER encodings of ASN.1 structures with differing ASN.1 tags, and of invalid BER encodings (such as OCTET STRINGs which are longer than their containing SEQUENCE.) | ||
|
||
For the VlvRequestControl constructor, throwing the exception early means that users can trust that only the values they explicitly specify are sent to the server - there are no circumstances where they can accidentally send `EF BF BD` to the server because they've passed a string which can't be encoded to valid UTF8 bytes. | ||
|
||
## Recommended action | ||
|
||
Servers should comply with the RFCs and specifications. Users should be aware of the need to handle an <xref:System.Text.EncoderFallbackException> when calling the <xref:System.DirectoryServices.Protocols.VlvRequestControl> constructor. | ||
|
||
## Affected APIs | ||
|
||
- <xref:System.DirectoryServices.Protocols.LdapConnection.SendRequest*?displayProperty=fullName> | ||
- <xref:System.DirectoryServices.Protocols.LdapConnection.EndSendRequest*?displayProperty=fullName> | ||
- <xref:System.DirectoryServices.Protocols.VlvRequestControl.%23ctor*> |
39 changes: 39 additions & 0 deletions
39
docs/core/compatibility/core-libraries/10.0/maccatalyst-version-normalization.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
--- | ||
title: "Breaking change: MacCatalyst version normalization" | ||
description: Learn about the .NET 10 breaking change in core .NET libraries where MacCatalyst version components are normalized. | ||
ms.date: 01/01/2025 | ||
--- | ||
|
||
# MacCatalyst version normalization | ||
|
||
This update ensures that MacCatalyst version components retrieved from the OS are always normalized to three components: major, minor, and build. The build component is set to `0` if undefined (`-1`), ensuring consistent behavior between iOS and MacCatalyst versions for version checks. | ||
|
||
## Previous behavior | ||
|
||
The build component in `Version` was not previously normalized, which led to incorrect version checks on MacCatalyst when only two components (major and minor) were provided. This resulted in invalid version checks. | ||
|
||
## New behavior | ||
|
||
The MacCatalyst build component is now normalized to `0`, ensuring consistent version checks. The revision component is always set to `-1`, as it is not specified on MacCatalyst or iOS. | ||
|
||
## Version introduced | ||
|
||
.NET 10 Preview 1 | ||
|
||
## Type of breaking change | ||
|
||
This change is a [behavioral change](../../categories.md#behavioral-change). | ||
|
||
## Reason for change | ||
|
||
Prevent incorrect version checks and align MacCatalyst versioning with iOS, ensuring consistent version components. | ||
|
||
## Recommended action | ||
|
||
Use versions of up to three components (major, minor, and build) on MacCatalyst. | ||
|
||
## Affected APIs | ||
|
||
- <xref:System.OperatingSystem.IsMacCatalystVersionAtLeast(System.Int32,System.Int32,System.Int32)?displayProperty=fullName> | ||
- <xref:System.OperatingSystem.IsOSPlatformVersionAtLeast(System.String,System.Int32,System.Int32,System.Int32,System.Int32)?displayProperty=fullName> | ||
- <xref:System.Environment.OSVersion?displayProperty=fullName> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to list the affected APIs for each in the Affected APIs section.