Description
The note under TargetFrameworks states:
If TargetFrameworks (plural) is specified, TargetFramework (singular) is ignored.
The actual SDK behavior is the opposite: a non-empty TargetFramework (singular) wins, and TargetFrameworks (plural) is ignored.
Evidence from the SDK source
Cross-targeting is only engaged when the singular property is empty — src/Tasks/Microsoft.NET.Build.Tasks/sdk/Sdk.targets:
<PropertyGroup Condition="'$(TargetFrameworks)' != '' and '$(TargetFramework)' == ''">
<IsCrossTargetingBuild>true</IsCrossTargetingBuild>
</PropertyGroup>
If TargetFramework is set (from the csproj, Directory.Build.props, or anywhere else), the project builds as a plain single-target project regardless of TargetFrameworks.
Repro
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
</PropertyGroup>
</Project>
dotnet build -c Release (SDK 10.0.111) produces only bin/Release/net8.0 - the plural property is ignored. Per the current doc text you would expect both net8.0 and net10.0 outputs.
Why it matters
The precedence determines behavior when the two properties are layered (e.g. Directory.Build.props sets one and a csproj sets the other) - a common pattern during incremental multi-targeting migrations. The current text leads reviewers and AI tooling to flag correct project files as broken (and vice versa).
Suggested correction
If TargetFramework (singular) is specified, TargetFrameworks (plural) is ignored and the project builds as a single-target project.
Document Details
⚠ Do not edit this section. It is required for learn.microsoft.com ➟ GitHub issue linking.
Description
The note under
TargetFrameworksstates:The actual SDK behavior is the opposite: a non-empty
TargetFramework(singular) wins, andTargetFrameworks(plural) is ignored.Evidence from the SDK source
Cross-targeting is only engaged when the singular property is empty —
src/Tasks/Microsoft.NET.Build.Tasks/sdk/Sdk.targets:If
TargetFrameworkis set (from the csproj,Directory.Build.props, or anywhere else), the project builds as a plain single-target project regardless ofTargetFrameworks.Repro
dotnet build -c Release(SDK 10.0.111) produces onlybin/Release/net8.0- the plural property is ignored. Per the current doc text you would expect bothnet8.0andnet10.0outputs.Why it matters
The precedence determines behavior when the two properties are layered (e.g.
Directory.Build.propssets one and a csproj sets the other) - a common pattern during incremental multi-targeting migrations. The current text leads reviewers and AI tooling to flag correct project files as broken (and vice versa).Suggested correction
Document Details
⚠ Do not edit this section. It is required for learn.microsoft.com ➟ GitHub issue linking.