Skip to content

Core libraries breaking changes for Preview 6 #41725

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

Merged
merged 2 commits into from
Jul 10, 2024
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
2 changes: 2 additions & 0 deletions docs/core/compatibility/9.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ If you're migrating an app to .NET 9, the breaking changes listed here might aff
| [Adding a ZipArchiveEntry with CompressionLevel sets ZIP central directory header general-purpose bit flags](core-libraries/9.0/compressionlevel-bits.md) | Behavioral change | Preview 5 |
| [API obsoletions with custom diagnostic IDs](core-libraries/9.0/obsolete-apis-with-custom-diagnostics.md) | Source incompatible | Preview 1 |
| [Creating type of array of System.Void not allowed](core-libraries/9.0/type-instance.md) | Behavioral change | Preview 1 |
| [Default `Equals()` and `GetHashCode()` throw for types marked with `InlineArrayAttribute`](core-libraries/9.0/inlinearrayattribute.md) | Behavioral change | Preview 6 |
| [Inline array struct size limit is enforced](core-libraries/9.0/inlinearray-size.md) | Behavioral change | Preview 1 |
| [InMemoryDirectoryInfo prepends rootDir to files](core-libraries/9.0/inmemorydirinfo-prepends-rootdir.md) | Behavioral change | Preview 1 |
| [RuntimeHelpers.GetSubArray returns different type](core-libraries/9.0/getsubarray-return.md) | Behavioral change | Preview 1 |
| [Support for empty environment variables](core-libraries/9.0/empty-env-variable.md) | Behavioral change | Preview 6 |

## Networking

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
title: "Breaking change: Support for empty environment variables"
description: Learn about the .NET 9 breaking change in core .NET libraries where passing `string.Empty` to `Environment.SetEnvironmentVariable` no longer deletes the environment variable.
ms.date: 07/10/2024
---
# Support for empty environment variables

Support was added to be able to set an environment variable to the empty string using <xref:System.Environment.SetEnvironmentVariable(System.String,System.String)?displayProperty=nameWithType>. As part of this work, the behavior of setting the <xref:System.Diagnostics.ProcessStartInfo.Environment?displayProperty=nameWithType> and <xref:System.Diagnostics.ProcessStartInfo.EnvironmentVariables?displayProperty=nameWithType> properties was changed to be consistent with that of <xref:System.Environment.SetEnvironmentVariable(System.String,System.String)?displayProperty=nameWithType>.

## Previous behavior

Previously:

- Both `Environment.SetEnvironmentVariable("TEST", string.Empty)` and `Environment.SetEnvironmentVariable("TEST", null)` deleted the environment variable.
- Both `ProcessStartInfo.Environment["TEST"] = string.Empty` and `ProcessStartInfo.Environment["TEST"] = null` set the environment variable in the child process to an empty value.

## New behavior

Starting in .NET 9:

- `Environment.SetEnvironmentVariable("TEST", string.Empty)` sets the environment variable value to an empty value. `Environment.SetEnvironmentVariable("TEST", null)` behavior is unchanged, that is, it still deletes the environment variable.
- `ProcessStartInfo.Environment["TEST"] = null` deletes the environment variable. `ProcessStartInfo.Environment["TEST"] = string.Empty` behavior is unchanged, that is, it still sets the environment variable to an empty value.

## Version introduced

.NET 9 Preview 6

## Type of breaking change

This change is a [behavioral change](../../categories.md#behavioral-change).

## Reason for change

Before this change, it wasn't possible to use <xref:System.Environment.SetEnvironmentVariable(System.String,System.String)?displayProperty=nameWithType> to set an environment variable to an empty value, which is a valid environment variable value on all supported platforms.

## Recommended action

To delete an environment variable using <xref:System.Environment.SetEnvironmentVariable(System.String,System.String)?displayProperty=nameWithType>, change your code to pass `null` instead of `string.Empty` as the value argument.

To set the environment variable to an empty value using <xref:System.Diagnostics.ProcessStartInfo.Environment?displayProperty=nameWithType> or <xref:System.Diagnostics.ProcessStartInfo.EnvironmentVariables?displayProperty=nameWithType>, change your code to set these properties to `string.Empty` instead of to `null`.

## Affected APIs

- <xref:System.Environment.SetEnvironmentVariable(System.String,System.String)?displayProperty=fullName>
- <xref:System.Diagnostics.ProcessStartInfo.Environment?displayProperty=fullName>
- <xref:System.Diagnostics.ProcessStartInfo.EnvironmentVariables?displayProperty=fullName>
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
title: "Breaking change: Default `Equals()` and `GetHashCode()` throw for types marked with `InlineArrayAttribute`"
description: Learn about the .NET 9 breaking change in core .NET libraries where the default implementations of `Equals()` and `GetHashCode()` throw an exception for types marked with `InlineArrayAttribute`.
ms.date: 07/10/2024
---
# Default `Equals()` and `GetHashCode()` throw for types marked with `InlineArrayAttribute`

The default behavior for <xref:System.ValueType.Equals(System.Object)> and <xref:System.ValueType.GetHashCode> on types marked with <xref:System.Runtime.CompilerServices.InlineArrayAttribute> is now to throw a <xref:System.NotSupportedException>. Library authors should override these two methods if they're expected to not throw.

## Previous behavior

Previously, the default implementations only used the placeholder `ref` field when computing equality or the hash code.

## New behavior

Starting in .NET 9, a <xref:System.NotSupportedException> is always thrown from the default implementations for <xref:System.ValueType.Equals(System.Object)> and <xref:System.ValueType.GetHashCode> when <xref:System.Runtime.CompilerServices.InlineArrayAttribute> is applied to a type.

## Version introduced

.NET 9 Preview 6

## Type of breaking change

This change is a [behavioral change](../../categories.md#behavioral-change).

## Reason for change

The current behavior is incorrect for both determining equality and computing the hash code, and users are led into a false sense of correctness when calling these functions.

## Recommended action

Library authors should implement both <xref:System.ValueType.Equals(System.Object)> and <xref:System.ValueType.GetHashCode> on all types marked with <xref:System.Runtime.CompilerServices.InlineArrayAttribute>.

## Affected APIs

- <xref:System.ValueType.Equals(System.Object)?displayProperty=fullName>
- <xref:System.ValueType.GetHashCode?displayProperty=fullName>
8 changes: 8 additions & 0 deletions docs/core/compatibility/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@ items:
href: core-libraries/9.0/compressionlevel-bits.md
- name: Creating type of array of System.Void not allowed
href: core-libraries/9.0/type-instance.md
- name: "`Equals`/`GetHashCode` throw for `InlineArrayAttribute` types"
href: core-libraries/9.0/inlinearrayattribute.md
- name: Inline array struct size limit is enforced
href: core-libraries/9.0/inlinearray-size.md
- name: InMemoryDirectoryInfo prepends rootDir to files
href: core-libraries/9.0/inmemorydirinfo-prepends-rootdir.md
- name: RuntimeHelpers.GetSubArray returns different type
href: core-libraries/9.0/getsubarray-return.md
- name: Support for empty environment variables
href: core-libraries/9.0/empty-env-variable.md
- name: Networking
items:
- name: HttpListenerRequest.UserAgent is nullable
Expand Down Expand Up @@ -1180,12 +1184,16 @@ items:
href: core-libraries/9.0/compressionlevel-bits.md
- name: Creating type of array of System.Void not allowed
href: core-libraries/9.0/type-instance.md
- name: "`Equals`/`GetHashCode` throw for `InlineArrayAttribute` types"
href: core-libraries/9.0/inlinearrayattribute.md
- name: Inline array struct size limit is enforced
href: core-libraries/9.0/inlinearray-size.md
- name: InMemoryDirectoryInfo prepends rootDir to files
href: core-libraries/9.0/inmemorydirinfo-prepends-rootdir.md
- name: RuntimeHelpers.GetSubArray returns different type
href: core-libraries/9.0/getsubarray-return.md
- name: Support for empty environment variables
href: core-libraries/9.0/empty-env-variable.md
- name: .NET 8
items:
- name: Activity operation name when null
Expand Down
Loading