关于 dotnet-version-upgrade
面向规划 .NET 版本迁移的开发者,涵盖受支持版本和预览版本。提供三种升级路径,以及 TFM、包更新、破坏性更改、弃用 API 和验证方面的指导。
主要功能
- 01在三种升级路径中作出选择
- 02更新 TFM、SDK 和包
- 03检测破坏性更改与弃用 API
- 04通过构建和测试验证迁移
- 05在防护措施下探索预览版升级
适用场景
- 01规划 LTS 到 LTS 的直接迁移
- 02因依赖限制分阶段升级
- 03在生产环境之外评估预览版
- 04检查库升级的 API 兼容性
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ wshaddix/ dotnet-skills --skill dotnet-version-upgrade安装后在 Claude Code 中输入/dotnet-version-upgrade确认已加载。
详细介绍
dotnet-version-upgrade
.NET 版本升级规划与执行的综合指南。此技能使用 [skill:dotnet-version-detection] 的结构化输出(当前 TFM、SDK 版本、预览版标志),并根据三个定义的升级路径提供可操作的升级指导。涵盖 TFM 迁移、包更新、重大更改检测、已弃用 API 替换和测试验证。
不在范围内: TFM 检测逻辑(由 [skill:dotnet-version-detection] 负责)、多目标项目设置和 polyfill 策略(参见 [skill:dotnet-multi-targeting])、云部署配置、CI/CD 管道更改。
交叉参考:[skill:dotnet-version-detection],用于 TFM 解析和版本矩阵;[skill:dotnet-multi-targeting],用于在迁移期间保持向后兼容性的 polyfill 优先多目标策略。
升级路径
根据项目需求和生态系统约束,选择合适的升级路径。
| 路径 | 迁移方案 | 使用场景 | 风险级别 |
|---|---|---|---|
| 生产(默认) | net8.0 -> net10.0 | LTS 到 LTS,适用于大多数应用的推荐方案 | 低——两个版本均为 LTS,支持周期较长 |
| 分阶段生产 | net8.0 -> net9.0 -> net10.0 | 生态系统依赖要求逐步迁移时 | 中——中间的 STS 版本支持周期较短 |
| 实验性 | net10.0 -> net11.0 (preview) | 在非生产环境中探索即将推出的功能 | 高——预览版 API 可能发生变化或被移除 |
路径选择决策流程
- 所有 NuGet 依赖项是否都支持目标 LTS?是 -> 生产路径(直接从 LTS 迁移到 LTS)。
- 是否有任何依赖项要求使用中间版本?是 -> 分阶段生产路径。
- 是否要为研发或概念验证探索预览功能?是 -> 实验性路径。
生产路径:LTS 到 LTS(net8.0 -> net10.0)
这是推荐的默认升级方案。.NET 8 和 .NET 10 均为长期支持版本,可实现稳定迁移,且重大更改均有完善文档说明。
升级检查清单
步骤 1:更新项目文件中的 TFM
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>
对于包含共享属性的解决方案:
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>
步骤 2:更新 global.json SDK 版本
{
"sdk": {
"version": "10.0.100",
"rollForward": "latestFeature"
}
}
步骤 3:更新 NuGet 包
使用 dotnet-outdated 检测过时的包,并确定哪些包需要更新以兼容 TFM:
# Install dotnet-outdated as a global tool
dotnet tool install -g dotnet-outdated-tool
# Check for outdated packages across the solution
dotnet outdated
# Check a specific project
dotnet outdated MyProject/MyProject.csproj
# Auto-upgrade to latest stable versions
dotnet outdated --upgrade
# Upgrade only to the latest minor/patch (safer)
dotnet outdated --upgrade --version-lock major
对于 ASP.NET Core 共享框架包,更新版本引用,使其与目标 TFM 匹配:
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.*" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.*" />
</ItemGroup>
步骤 4:检查重大更改
# Build to surface warnings and errors
dotnet build --warnaserror
# Run analyzers for deprecated API usage
dotnet build /p:TreatWarningsAsErrors=true
查阅官方重大更改列表:
步骤 5:替换已弃用的 API
从 net8.0 升级到 net10.0 时的常见替换方案:
| 已弃用项 | 替换方案 | 备注 |
|---|---|---|
BinaryFormatter | System.Text.Json 或 MessagePack | 从 net9.0 开始,BinaryFormatter 会引发 PlatformNotSupportedException |
Thread.Abort() | 使用 CancellationToken 进行协作式取消 | Thread.Abort() 会引发 PlatformNotSupportedException |
WebRequest / HttpWebRequest | 通过 IHttpClientFactory 使用 HttpClient | 已过时(SYSLIB0014),请迁移到 HttpClient |
建议的现代化改进(并非已弃用,但可提升性能和 AOT 就绪度):
| 模式 | 改进方案 | 备注 |
|---|---|---|
未使用源生成的 Regex | [GeneratedRegex] 特性 | 源生成的正则表达式速度更快,并且兼容 AOT |
步骤 6:运行测试并验证
# Run full test suite
dotnet test --configuration Release
# Enable trim/AOT analyzers to surface compatibility warnings without publishing
dotnet build --configuration Release /p:EnableTrimAnalyzer=true /p:EnableAotAnalyzer=true
.NET Upgrade Assistant
.NET Upgrade Assistant 可自动完成部分迁移流程。它最适用于包含多个项目的大型解决方案。
# Install as a global tool
dotnet tool install -g upgrade-assistant
# Analyze a project (non-destructive, reports recommendations)
upgrade-assistant analyze MyProject/MyProject.csproj
# Perform the upgrade (modifies files)
upgrade-assistant upgrade MyProject/MyProject.csproj
何时使用 Upgrade Assistant:
- 包含多个项目且依赖关系图复杂的大型解决方案
- 从旧版 .NET Framework 迁移到现代 .NET
- 在提交升级之前需要全面分析依赖关系
限制:
- 可能无法处理所有破坏性变更——仍需手动审查
- 自定义 MSBuild 扩展和第三方构建工具可能需要手动调整
- 不会更新运行时行为差异——完善的测试覆盖至关重要
- 对依赖项较少的小型项目没有必要(手动更新 TFM 更简单)
分阶段生产路径:net8.0 -> net9.0 -> net10.0
当生态系统限制阻碍直接从一个 LTS 版本迁移到下一个 LTS 版本时,请使用分阶段路径。通过 .NET 9(STS)分阶段迁移,可以实现渐进式迁移。
何时分阶段迁移到 .NET 9
- **第三方包兼容性:**某个关键依赖项仅支持 net9.0(尚不支持 net10.0),而你需要立即从 net8.0 升级。
- **大量破坏性变更:**从 net8.0 升级到 net10.0 涉及的破坏性变更过多,无法一次性处理;分步迁移可降低风险。
- **渐进式验证:**你希望在继续迁移之前,逐步验证每个阶段的行为变更。
.NET 9 背景
.NET 9 是一个标准支持期限(STS)版本:
- **正式发布:**2024 年 11 月
- **支持结束:**2026 年 5 月(自正式发布起 18 个月)
- **C# 版本:**C# 13
由于 .NET 9 即将结束支持,请勿停留在 net9.0。请在开始第一阶段迁移之前,规划好第二阶段迁移(net9.0 -> net10.0)。
分阶段升级检查清单
第一阶段:net8.0 -> net9.0
- 在 .csproj /
Directory.Build.props中将 TFM 更新为net9.0 - 将
global.json中的 SDK 更新为9.0.xxx - 运行
dotnet outdated --upgrade更新包 - 查看 .NET 9 破坏性变更
- 替换由
SYSLIB诊断和CS0618警告指出的已弃用 API(例如,BinaryFormatter->System.Text.Json) - 运行
dotnet test --configuration Release进行验证 - 部署到预发布环境,并通过监控在生产环境中验证
第二阶段:net9.0 -> net10.0
- 在 .csproj /
Directory.Build.props中将 TFM 更新为net10.0 - 将
global.json中的 SDK 更新为10.0.xxx - 再次运行
dotnet outdated --upgrade - 查看 .NET 10 破坏性变更
- 替换 net9.0 到 net10.0 之间引入的其他已弃用 API
- 运行
dotnet test --configuration Release进行验证 - 部署到预发布环境,并移除任何针对 net9.0 的变通方案
**时间安排建议:**在 .NET 9 支持期限内(2026 年 5 月之前)完成两个阶段的迁移。在已停止支持的 STS 版本上运行生产工作负载,会使你面临未修补的安全漏洞。
实验路径:net10.0 -> net11.0(预览版)
用于非生产环境中探索即将推出的功能。目前 .NET 11 仍处于预览阶段,其 API 在正式发布前可能会变更或移除。
安全措施
- **仅限非生产环境。**请勿将目标为预览版的代码部署到生产环境。
- **使用独立分支或项目。**将实验工作与生产代码库隔离。
- **固定预览版 SDK。**使用
global.json锁定特定预览版 SDK,以避免不同预览版本之间出现未察觉的行为变更。 - **预期不同预览版本之间会有破坏性变更。**标记为
[RequiresPreviewFeatures]的 API 可能会在不同预览版本之间改变形式。
启用预览功能
步骤 1:安装预览版 SDK
# Verify installed SDKs
dotnet --list-sdks
# Example: 11.0.100-preview.1.xxxxx should appear
步骤 2:在 global.json 中固定使用预览版 SDK
{
"sdk": {
"version": "11.0.100-preview.1.25120.13",
"rollForward": "disable"
}
}
使用 "rollForward": "disable",防止在不同预览版之间自动升级 SDK 版本。
步骤 3:设置 TFM 并启用预览功能
<PropertyGroup>
<TargetFramework>net11.0</TargetFramework>
<LangVersion>preview</LangVersion>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
</PropertyGroup>
步骤 4:启用 runtime-async(可选)
Runtime-async 将 async/await 从编译器生成的状态机迁移到运行时级别执行,从而减少分配并提升异步密集型工作负载的性能:
<PropertyGroup>
<TargetFramework>net11.0</TargetFramework>
<LangVersion>preview</LangVersion>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<Features>$(Features);runtime-async=on</Features>
</PropertyGroup>
Runtime-async 需要同时启用 EnablePreviewFeatures 和 Features 标志。它属于实验性功能,在正式发布前可能会发生重大变化。
实验性升级检查清单
- 安装 .NET 11 预览版 SDK,并在
global.json中使用"rollForward": "disable"固定版本 - 将 TFM 更新为
net11.0,并设置<LangVersion>preview</LangVersion>+<EnablePreviewFeatures>true</EnablePreviewFeatures> - 运行
dotnet outdated,检查包与预览版 TFM 的兼容性 - 构建并检查警告——预览版 SDK 可能会报告新的
SYSLIB诊断或CA2252(预览功能用法) - 替换新分析器版本发现的所有已弃用 API
- 运行
dotnet test进行验证——预计部分第三方包尚不支持预览版 TFM - 记录发现的问题,以便规划后续生产环境升级
探索 .NET 11 预览版的内容
| 功能 | 领域 | 说明 |
|---|---|---|
| Runtime-async | 性能 | 运行时级别的 Async/await;需要选择启用 |
| Zstandard 压缩 | I/O | System.IO.Compression.Zstandard;速度比 Brotli 快 2-7 倍 |
| BFloat16 | 数值计算 | 面向 AI/ML 工作负载的 System.Numerics.BFloat16 |
| Happy Eyeballs | 网络 | 用于双栈 IPv4/IPv6 的 ConnectAlgorithm.Parallel |
| C# 15 预览功能 | 语言 | 集合表达式参数(with() 语法) |
| WASM 上的 CoreCLR | 运行时 | Blazor WASM 中 Mono 的实验性替代方案 |
破坏性变更检测
在任何升级过程中,系统地识别和解决破坏性变更。
构建时检测
# Clean build to surface all warnings (not just incremental)
dotnet clean && dotnet build --no-incremental
# Treat warnings as errors to catch deprecation notices
dotnet build /p:TreatWarningsAsErrors=true
# List specific obsolete API warnings
dotnet build 2>&1 | grep -E "CS0618|CS0612"
CS0618:使用带有消息的[Obsolete]成员CS0612:使用不带消息的[Obsolete]成员CS8073:表达式始终计算为同一值(类型行为变更)
分析器诊断
启用 .NET 分析器以检测其他问题:
<PropertyGroup>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<AnalysisLevel>latest-recommended</AnalysisLevel>
</PropertyGroup>
升级时需关注的分析器类别:
CA1422:平台兼容性(目标平台上已移除 API)CA1416:未使用防护措施的平台特定 APICA2252:选择使用预览功能SYSLIB0XXX:已弃用系统 API 的诊断(例如,针对 BinaryFormatter 的SYSLIB0011)
API 差异工具
对于库作者,可使用 API 兼容性工具验证公共接口变更:
# Package validation detects breaking changes against a baseline
dotnet pack /p:EnablePackageValidation=true /p:PackageValidationBaselineVersion=1.0.0
# Standalone API comparison
dotnet tool install -g Microsoft.DotNet.ApiCompat.Tool
apicompat --left-assembly bin/Release/net8.0/MyLib.dll \
--right-assembly bin/Release/net10.0/MyLib.dll
有关 API 兼容性验证工作流的详细信息(包括抑制文件和 CI 集成),请参阅 [skill:dotnet-multi-targeting]。
包更新策略
dotnet-outdated
dotnet-outdated 工具全面展示包的过时情况:
# Install
dotnet tool install -g dotnet-outdated-tool
# Show all outdated packages with current vs latest versions
dotnet outdated
# Lock major version, show only minor/patch updates (safer incremental upgrades)
dotnet outdated --version-lock major
# Auto-upgrade with version locking to avoid unexpected major bumps
dotnet outdated --upgrade --version-lock major
# Output as JSON for CI integration
dotnet outdated --output-format json
中央包管理
对于使用中央包管理(Directory.Packages.props)的解决方案,可集中更新版本:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.*" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="10.*" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.*" />
<PackageVersion Include="Serilog" Version="4.*" />
</ItemGroup>
</Project>
Directory.Packages.props 会从项目目录开始逐级向上解析。在单体仓库结构中,请确认嵌套的 Directory.Packages.props 文件没有遮蔽根目录级别的配置。
ASP.NET Core 共享框架包
ASP.NET Core 共享框架包的主版本必须与目标 TFM 一致。以下两种方式均有效:
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.*" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.1" />
</ItemGroup>
为确保 CI 的确定性,建议固定版本;在探索性升级期间,使用浮动版本也很有用。无论采用哪种方式,主版本必须与 TFM 一致(例如,net10.0 对应 10.x)。
Agent 注意事项
-
未经验证生态系统兼容性,不要跳过 .NET 9。 虽然从 LTS 升级到 LTS(net8.0 -> net10.0)是推荐的默认做法,但某些第三方包可能只支持将 net9.0 作为中间步骤。选择升级路径前,请检查包的兼容性。
-
不要在生产工作负载中使用预览版 SDK。 .NET 11 预览版 API 不稳定,并且会在不同预览版之间发生变化。请将实验性工作隔离在单独的分支或项目中,并固定预览版 SDK 的版本。
-
不要假设 .NET 9 STS 的支持期为 12 个月。 STS 生命周期为 GA 发布后 18 个月。.NET 9 于 2024 年 11 月发布 GA,因此支持将于 2026 年 5 月结束。请始终根据实际 GA 日期计算,而非根据发布年份计算。
-
确保 ASP.NET 共享框架包的主版本与 TFM 匹配。
Microsoft.AspNetCore.Mvc.Testing等包的主版本必须与项目 TFM 对齐(例如,net10.0对应10.x)。为确保 CI 构建具有确定性,请固定确切版本;在探索性升级期间,也可以使用通配符(例如,10.*)。 -
不要重新实现 TFM 检测。 此技能使用 [skill:dotnet-version-detection] 提供的结构化输出。切勿解析
.csproj文件来确定当前版本——请使用检测技能的输出(TFM、C# 版本、SDK 版本、警告)。 -
不要将
dotnet-outdated --upgrade视为完整解决方案。 它会更新包版本,但不会处理这些包中的重大 API 更改。升级包后,务必构建、测试并查看变更日志。 -
不要在预览版 SDK 中使用
"rollForward": "latestMajor"。 这可能会悄然切换到具有破坏性更改的其他预览版本。对于预览版 SDK,请使用"rollForward": "disable",以确保构建可复现。 -
不要忽略
Directory.Packages.props的层级结构。 在 monorepo 结构中,嵌套的Directory.Packages.props文件会覆盖父级配置。升级时,请从项目目录向上查找所有可能影响包解析的Directory.Packages.props文件。 -
升级时不要忽略
SYSLIB诊断代码。 这些系统级过时警告(例如,BinaryFormatter 对应的SYSLIB0011、WebRequest 对应的SYSLIB0014)表示相关 API 在较新的 TFM 上会在运行时抛出异常,而不仅仅是编译时警告。
先决条件
- 已安装目标 TFM 对应的 .NET SDK(例如,升级到 net10.0 需要 .NET 10 SDK)
dotnet-outdated-tool(用于检测过时的包):dotnet tool install -g dotnet-outdated-toolupgrade-assistant(可选,用于自动迁移):dotnet tool install -g upgrade-assistant- [skill:dotnet-version-detection] 的输出(当前 TFM、SDK 版本、预览标记)
参考资料
最后验证日期:2026-02-12