diff --git a/docs/core/compatibility/10.md b/docs/core/compatibility/10.md index 1b4158ecf9416..e3705fdec883e 100644 --- a/docs/core/compatibility/10.md +++ b/docs/core/compatibility/10.md @@ -119,6 +119,7 @@ See [Breaking changes in EF Core 10](/ef/core/what-is-new/ef-core-10.0/breaking- | [`dotnet` CLI commands log non-command-relevant data to stderr](sdk/10.0/dotnet-cli-stderr-output.md) | Behavioral change | | [.NET tool packaging creates RuntimeIdentifier-specific tool packages](sdk/10.0/dotnet-tool-pack-publish.md) | Behavioral change | | [Default workload configuration from 'loose manifests' to 'workload sets' mode](sdk/10.0/default-workload-config.md) | Behavioral change | +| [`DefineConstants` for target frameworks not available at evaluation time](sdk/10.0/defineconstants-not-available-at-evaluation.md) | Behavioral change | | [Code coverage EnableDynamicNativeInstrumentation defaults to false](sdk/10.0/code-coverage-dynamic-native-instrumentation.md) | Behavioral change | | [dnx.ps1 file is no longer included in .NET SDK](sdk/10.0/dnx-ps1-removed.md) | Source incompatible | | [Double quotes in file-level directives are disallowed](sdk/10.0/file-level-directive-double-quotes.md) | Source incompatible | diff --git a/docs/core/compatibility/sdk/10.0/defineconstants-not-available-at-evaluation.md b/docs/core/compatibility/sdk/10.0/defineconstants-not-available-at-evaluation.md new file mode 100644 index 0000000000000..c41cd865bbc87 --- /dev/null +++ b/docs/core/compatibility/sdk/10.0/defineconstants-not-available-at-evaluation.md @@ -0,0 +1,69 @@ +--- +title: "Breaking change: `DefineConstants` for target frameworks not available at evaluation time" +description: "Learn about the breaking change in .NET 10 SDK where DefineConstants items for target frameworks are no longer available at MSBuild evaluation time." +ms.date: 03/12/2026 +ai-usage: ai-assisted +ms.custom: https://github.com/dotnet/docs/issues/51763 +--- + +# `DefineConstants` for target frameworks not available at evaluation time + +The target-framework-related `DefineConstants` items (such as `NET`, `NET9_0_OR_GREATER`, `NETSTANDARD2_0`, and similar constants) are no longer computed at MSBuild evaluation time. Using these constants in MSBuild `Condition` attributes in your project file will no longer work as expected. + +## Version introduced + +.NET 10 + +## Previous behavior + +Previously, `DefineConstants` values like `NET`, `NETFRAMEWORK`, and `NETSTANDARD` (with optional version and `_OR_GREATER` suffixes, such as `NET452_OR_GREATER` or `NET9_0_OR_GREATER`) were available during MSBuild evaluation. This allowed you to use them directly in `Condition` attributes in your project file: + +```xml + + + +``` + +## New behavior + +Starting in .NET 10, the target-framework `DefineConstants` values are computed in a `Target`, not during MSBuild evaluation. As a result, `Condition` attributes that inspect `DefineConstants` for TFM-related values evaluate before those values are set and no longer trigger as expected. + +For example, the following condition no longer evaluates correctly because `NET9_0_OR_GREATER` isn't present in `DefineConstants` at evaluation time: + +```xml + + + + +``` + +## Type of breaking change + +This change is a [behavioral change](../../categories.md#behavioral-change). + +## Reason for change + +Direct access or manipulation of `DefineConstants` led to users accidentally overwriting the values. In addition, moving the computation into a `Target` enables more complex MSBuild orchestration scenarios required by other tools. + +## Recommended action + +- **Do not** inspect `DefineConstants` for TFM-related values (for example, `NET9_0_OR_GREATER`, `NETSTANDARD2_0`, and similar) in MSBuild `Condition` attributes at evaluation time. +- **Do** use the documented [MSBuild `TargetFramework` and `TargetPlatform` functions](/visualstudio/msbuild/property-functions#msbuild-targetframework-and-targetplatform-functions) to check for target-framework compatibility. For example: + + ```xml + + + + + + + + + + ``` + +- **Continue** to use `DefineConstants` in `Condition` attributes for constants that you define and control yourself. This change only affects the TFM-related constants that the SDK sets automatically. + +## Affected APIs + +None. diff --git a/docs/core/compatibility/toc.yml b/docs/core/compatibility/toc.yml index 060aa02d24c20..4ec2006476ece 100644 --- a/docs/core/compatibility/toc.yml +++ b/docs/core/compatibility/toc.yml @@ -164,6 +164,8 @@ items: href: sdk/10.0/nugetaudit-transitive-packages.md - name: project.json not supported in `dotnet restore` href: sdk/10.0/dotnet-restore-project-json-unsupported.md + - name: "`DefineConstants` for target frameworks not available at evaluation time" + href: sdk/10.0/defineconstants-not-available-at-evaluation.md - name: Default workload configuration from 'loose manifests' to 'workload sets' mode href: sdk/10.0/default-workload-config.md - name: "`dotnet new sln` defaults to SLNX file format"