dotnet-modernize
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesedotnet-modernize
dotnet-modernize
Analyze existing .NET code for modernization opportunities. Identifies outdated target frameworks, deprecated packages, superseded API patterns, and missing modern best practices. Provides actionable recommendations for each finding.
Scope boundary: This skill flags opportunities only. For actual migration paths, polyfill strategies, multi-targeting guidance, and step-by-step version upgrade procedures, see [skill:dotnet-version-upgrade] and [skill:dotnet-multi-targeting].
Prerequisites: Run [skill:dotnet-version-detection] first to determine the current SDK, TFM, and language version. Run [skill:dotnet-project-analysis] to understand solution structure and dependencies.
Cross-references: [skill:dotnet-project-structure] for modern layout conventions, [skill:dotnet-add-analyzers] for analyzer-based detection of deprecated patterns, [skill:dotnet-scaffold-project] for the target state of a fully modernized project.
分析现有.NET代码的现代化优化机会。识别过时的目标框架(TFM)、已弃用的包、被替代的API模式以及缺失的现代化最佳实践,并针对每个问题提供可执行的建议。
范围说明: 本技能仅负责标记优化机会。如需实际迁移路径、兼容填充策略、多目标框架指导以及分步版本升级流程,请查看 [skill:dotnet-version-upgrade] 和 [skill:dotnet-multi-targeting]。
前置条件: 请先运行 [skill:dotnet-version-detection] 以确定当前SDK、TFM和语言版本。运行 [skill:dotnet-project-analysis] 以了解解决方案结构和依赖关系。
交叉参考:[skill:dotnet-project-structure] 提供现代化布局规范,[skill:dotnet-add-analyzers] 基于分析器检测已弃用模式,[skill:dotnet-scaffold-project] 展示完全现代化项目的目标状态。
Modernization Checklist
现代化检查清单
Run through this checklist against the existing codebase. Each section identifies what to look for and what the modern replacement is.
针对现有代码库逐一检查以下内容。每个部分会说明需要关注的点以及对应的现代化替代方案。
1. Target Framework
1. 目标框架(Target Framework)
Check in files (or ):
<TargetFramework>.csprojDirectory.Build.props| Current TFM | Status | Recommendation |
|---|---|---|
| LTS -- supported until Nov 2026 | Plan upgrade to |
| STS -- support ends May 2026 | Upgrade to |
| End of life | Upgrade immediately |
| End of life | Upgrade immediately |
| End of life | Upgrade immediately |
| Supported (library compat) | Keep if multi-targeting for broad reach |
| End of life | Upgrade immediately |
| Legacy | Evaluate migration feasibility |
To scan all projects:
bash
undefined检查 文件(或 )中的 :
.csprojDirectory.Build.props<TargetFramework>| 当前TFM | 状态 | 建议 |
|---|---|---|
| 长期支持版(LTS)——支持至2026年11月 | 计划升级至 |
| 标准支持版(STS)——支持至2026年5月 | 及时升级至 |
| 已终止支持 | 立即升级 |
| 已终止支持 | 立即升级 |
| 已终止支持 | 立即升级 |
| 受支持(库兼容性) | 若需多目标框架以覆盖广泛场景则保留 |
| 已终止支持 | 立即升级 |
| 遗留版本 | 评估迁移可行性 |
扫描所有项目的命令:
bash
undefinedFind all TFMs in the solution
Find all TFMs in the solution
find . -name "*.csproj" -exec grep -h "TargetFramework" {} ; | sort -u
find . -name "*.csproj" -exec grep -h "TargetFramework" {} ; | sort -u
Check Directory.Build.props
Check Directory.Build.props
grep "TargetFramework" Directory.Build.props 2>/dev/null
---grep "TargetFramework" Directory.Build.props 2>/dev/null
---2. Deprecated and Superseded Packages
2. 已弃用和被替代的包
Scan (or individual files) for packages that have been superseded:
Directory.Packages.props.csproj| Deprecated Package | Replacement | Since |
|---|---|---|
| | .NET 8 |
| | .NET Core 3.0+ |
| Built-in STJ | .NET Core 3.0+ |
| Built-in OpenAPI ( | .NET 9 |
| Built-in OpenAPI for document generation; keep NSwag if using client generation or Swagger UI features | .NET 9 |
| Built-in logging + | .NET Core 2.0+ |
| Remove explicit PackageReference — included in | .NET Core 3.0+ |
| | .NET Core 3.0+ |
| | 2020+ |
| | 2020+ |
| | 2020+ |
| | 2020+ |
| | .NET Core 1.0+ |
| | .NET Core+ |
| Manual mapping or source-generated mappers | Preference |
To scan for deprecated packages:
bash
undefined扫描 (或单个 文件)以找出被替代的包:
Directory.Packages.props.csproj| 已弃用包 | 替代方案 | 起始版本 |
|---|---|---|
| | .NET 8 |
| | .NET Core 3.0+ |
| 内置STJ | .NET Core 3.0+ |
| 内置OpenAPI( | .NET 9 |
| 内置OpenAPI用于文档生成;若使用客户端生成或Swagger UI功能则保留NSwag | .NET 9 |
| 内置日志 + | .NET Core 2.0+ |
| 移除显式PackageReference —— 已包含在 | .NET Core 3.0+ |
| | .NET Core 3.0+ |
| | 2020+ |
| | 2020+ |
| | 2020+ |
| | 2020+ |
| | .NET Core 1.0+ |
| | .NET Core+ |
| 手动映射或源生成映射器 | 按需选择 |
扫描已弃用包的命令:
bash
undefinedList all package references
List all package references
grep -rh "PackageVersion|PackageReference"
Directory.Packages.props $(find . -name "*.csproj") 2>/dev/null |
grep -i "Include=" | sort -u
Directory.Packages.props $(find . -name "*.csproj") 2>/dev/null |
grep -i "Include=" | sort -u
**Note on Newtonsoft.Json:** Existing projects with deep Newtonsoft.Json usage (custom converters, `JObject` manipulation) may not benefit from immediate migration. Flag it but assess the migration cost.
---grep -rh "PackageVersion|PackageReference"
Directory.Packages.props $(find . -name "*.csproj") 2>/dev/null |
grep -i "Include=" | sort -u
Directory.Packages.props $(find . -name "*.csproj") 2>/dev/null |
grep -i "Include=" | sort -u
**关于Newtonsoft.Json的说明:** 若现有项目深度依赖Newtonsoft.Json(如自定义转换器、`JObject`操作),可能无法从立即迁移中获益。标记该问题并评估迁移成本。
---3. Superseded API Patterns
3. 被替代的API模式
Look for code patterns that have modern replacements:
寻找具有现代化替代方案的代码模式:
Startup.cs / Program.cs Pattern
Startup.cs / Program.cs 模式
Old (pre-.NET 6):
csharp
public class Startup
{
public void ConfigureServices(IServiceCollection services) { }
public void Configure(IApplicationBuilder app) { }
}Modern (minimal hosting):
csharp
var builder = WebApplication.CreateBuilder(args);
// ConfigureServices equivalent
var app = builder.Build();
// Configure equivalent
app.Run();旧版(.NET 6之前):
csharp
public class Startup
{
public void ConfigureServices(IServiceCollection services) { }
public void Configure(IApplicationBuilder app) { }
}现代化版(最小托管模型):
csharp
var builder = WebApplication.CreateBuilder(args);
// 对应ConfigureServices
var app = builder.Build();
// 对应Configure
app.Run();HttpClient Registration
HttpClient 注册
Old:
csharp
services.AddHttpClient<MyService>(client =>
{
client.BaseAddress = new Uri("https://api.example.com");
})
.AddTransientHttpErrorPolicy(p => p.WaitAndRetryAsync(3, _ => TimeSpan.FromMilliseconds(300)));Modern (with Microsoft.Extensions.Resilience):
csharp
services.AddHttpClient<MyService>(client =>
{
client.BaseAddress = new Uri("https://api.example.com");
})
.AddStandardResilienceHandler();旧版:
csharp
services.AddHttpClient<MyService>(client =>
{
client.BaseAddress = new Uri("https://api.example.com");
})
.AddTransientHttpErrorPolicy(p => p.WaitAndRetryAsync(3, _ => TimeSpan.FromMilliseconds(300)));现代化版(使用Microsoft.Extensions.Resilience):
csharp
services.AddHttpClient<MyService>(client =>
{
client.BaseAddress = new Uri("https://api.example.com");
})
.AddStandardResilienceHandler();Synchronous I/O
同步I/O操作
Flag: , , without suffix.
File.ReadAllTextStream.ReadHttpClientAsyncModern: Use variants -- , , .
asyncFile.ReadAllTextAsyncStream.ReadAsyncawait httpClient.GetAsync()标记点: 、、不带后缀的方法。
File.ReadAllTextStream.ReadAsyncHttpClient现代化方案: 使用异步变体 —— 、、。
File.ReadAllTextAsyncStream.ReadAsyncawait httpClient.GetAsync()String Concatenation in Hot Paths
热点路径中的字符串拼接
Flag: String concatenation () or in logging, loops.
+String.FormatModern: Use string interpolation with source generators, or .
LoggerMessageStringBuilder标记点: 日志、循环中使用字符串拼接()或。
+String.Format现代化方案: 使用源生成器的字符串插值,或。
LoggerMessageStringBuilderLegacy Collection Patterns
遗留集合模式
Flag: , , non-generic collections.
HashtableArrayListModern: , , generic collections.
Dictionary<TKey, TValue>List<T>标记点: 、、非泛型集合。
HashtableArrayList现代化方案: 、、泛型集合。
Dictionary<TKey, TValue>List<T>ILogger Pattern
ILogger 模式
Old:
csharp
_logger.LogInformation("Processing order {OrderId}", orderId);Modern (high-performance):
csharp
[LoggerMessage(Level = LogLevel.Information, Message = "Processing order {OrderId}")]
static partial void LogProcessingOrder(ILogger logger, string orderId);旧版:
csharp
_logger.LogInformation("Processing order {OrderId}", orderId);现代化版(高性能):
csharp
[LoggerMessage(Level = LogLevel.Information, Message = "Processing order {OrderId}")]
static partial void LogProcessingOrder(ILogger logger, string orderId);4. Missing Modern Build Configuration
4. 缺失的现代化构建配置
Check for the absence of recommended build infrastructure:
| Missing | Check | Recommendation |
|---|---|---|
| Central Package Management | No | See [skill:dotnet-project-structure] |
| Directory.Build.props | Properties scattered across | Centralize shared properties |
| .editorconfig | No | See [skill:dotnet-project-structure] |
| global.json | No SDK pinning | Add for reproducible builds |
| NuGet audit | No | Enable in |
| Lock files | No | Enable for deterministic restores |
| Package source mapping | No | Add for supply-chain security |
| Analyzers | No | See [skill:dotnet-add-analyzers] |
| SourceLink | No SourceLink package reference | Add for debugger source navigation |
| Nullable reference types | | Enable globally |
| .slnx | Still using | Migrate with |
检查是否缺少推荐的构建基础设施:
| 缺失项 | 检查方式 | 建议 |
|---|---|---|
| 中央包管理(Central Package Management) | 无 | 查看 [skill:dotnet-project-structure] |
| Directory.Build.props | 属性分散在多个 | 集中共享属性 |
| .editorconfig | 仓库根目录无 | 查看 [skill:dotnet-project-structure] |
| global.json | 未固定SDK版本 | 添加以实现可复现构建 |
| NuGet审计 | 无 | 在 |
| 锁定文件 | 无 | 启用以实现确定性还原 |
| 包源映射 | | 添加以提升供应链安全性 |
| 分析器 | 无 | 查看 [skill:dotnet-add-analyzers] |
| SourceLink | 无SourceLink包引用 | 添加以支持调试器源码导航 |
| 可空引用类型 | 未启用 | 全局启用 |
| .slnx | .NET 9+ SDK仍使用 | 使用 |
5. Deprecated C# Language Patterns
5. 已弃用的C#语言模式
| Old Pattern | Modern Replacement | Language Version |
|---|---|---|
| | C# 8 |
| | C# 9 |
| Target-typed | C# 9 |
| Block-scoped namespaces | File-scoped namespaces | C# 10 |
| | C# 10 |
| Manual string concatenation for multi-line | Raw string literals ( | C# 11 |
Explicit interface dispatch for | Generic math interfaces | C# 11 |
| Improved enum pattern matching | C# 11+ |
| Lambda without natural type | Natural function types | C# 10+ |
| | C# all |
| Primary constructor classes (manual) | Primary constructors on | C# 12 |
Multiple | | C# 11+ |
| | C# 13 |
Lock with | | C# 13 |
| 旧模式 | 现代化替代方案 | 语言版本 |
|---|---|---|
带 | | C# 8 |
| | C# 9 |
显式类型的 | 目标类型 | C# 9 |
| 块级命名空间 | 文件级命名空间 | C# 10 |
| 带位置参数的 | C# 10 |
| 手动拼接多行字符串 | 原始字符串字面量( | C# 11 |
| 泛型数学接口 | C# 11 |
| 改进的枚举模式匹配 | C# 11+ |
| 无自然类型的Lambda表达式 | 自然函数类型 | C# 10+ |
手动包装 | 带 | 所有C#版本 |
| 手动实现主构造函数的类 | | C# 12 |
多个 | 基于类型和列表模式的 | C# 11+ |
| | C# 13 |
使用 | | C# 13 |
6. Security and Compliance
6. 安全与合规
| Issue | Detection | Fix |
|---|---|---|
| Known vulnerabilities | | Update affected packages |
| Deprecated packages | | Replace with successors |
| Outdated packages | | Evaluate updates |
| Missing HTTPS redirection | No | Add to pipeline |
| Missing HSTS | No | Add for production |
| Hardcoded secrets | Connection strings in | Use User Secrets or Key Vault |
bash
undefined| 问题 | 检测方式 | 修复方案 |
|---|---|---|
| 已知漏洞 | | 更新受影响的包 |
| 已弃用包 | | 替换为继任包 |
| 过时包 | | 评估更新必要性 |
| 缺失HTTPS重定向 | 无 | 添加到管道中 |
| 缺失HSTS | 无 | 生产环境添加 |
| 硬编码密钥 | | 使用用户密钥或密钥保管库 |
bash
undefinedRun all NuGet audits
Run all NuGet audits
dotnet list package --vulnerable --include-transitive
dotnet list package --deprecated
dotnet list package --outdated
---dotnet list package --vulnerable --include-transitive
dotnet list package --deprecated
dotnet list package --outdated
---Running a Modernization Scan
运行现代化扫描
Combine the checks into a systematic scan:
bash
undefined将所有检查整合为系统化扫描:
bash
undefined1. Check TFMs
1. Check TFMs
echo "=== Target Frameworks ==="
find . -name ".csproj" -exec grep -Hl "TargetFramework" {} ; | while read f; do
echo "$f: $(grep -o '<TargetFramework[s]>[^<]*' "$f" | head -1)"
done
echo "=== Target Frameworks ==="
find . -name ".csproj" -exec grep -Hl "TargetFramework" {} ; | while read f; do
echo "$f: $(grep -o '<TargetFramework[s]>[^<]*' "$f" | head -1)"
done
2. Check for deprecated packages
2. Check for deprecated packages
echo "=== Package Audit ==="
dotnet list package --deprecated 2>/dev/null
dotnet list package --vulnerable --include-transitive 2>/dev/null
echo "=== Package Audit ==="
dotnet list package --deprecated 2>/dev/null
dotnet list package --vulnerable --include-transitive 2>/dev/null
3. Check build infrastructure
3. Check build infrastructure
echo "=== Build Infrastructure ==="
test -f Directory.Build.props && echo "OK: Directory.Build.props" || echo "MISSING: Directory.Build.props"
test -f Directory.Packages.props && echo "OK: Directory.Packages.props (CPM)" || echo "MISSING: Directory.Packages.props"
test -f .editorconfig && echo "OK: .editorconfig" || echo "MISSING: .editorconfig"
test -f global.json && echo "OK: global.json" || echo "MISSING: global.json"
test -f nuget.config && echo "OK: nuget.config" || echo "MISSING: nuget.config"
echo "=== Build Infrastructure ==="
test -f Directory.Build.props && echo "OK: Directory.Build.props" || echo "MISSING: Directory.Build.props"
test -f Directory.Packages.props && echo "OK: Directory.Packages.props (CPM)" || echo "MISSING: Directory.Packages.props"
test -f .editorconfig && echo "OK: .editorconfig" || echo "MISSING: .editorconfig"
test -f global.json && echo "OK: global.json" || echo "MISSING: global.json"
test -f nuget.config && echo "OK: nuget.config" || echo "MISSING: nuget.config"
4. Check for old patterns in code
4. Check for old patterns in code
echo "=== Code Patterns ==="
grep -rl "class Startup" --include=".cs" . 2>/dev/null && echo "FOUND: Legacy Startup.cs pattern"
grep -rl "Microsoft.Extensions.Http.Polly" --include=".csproj" --include=".props" . 2>/dev/null && echo "FOUND: Deprecated Polly package"
grep -rl "Swashbuckle" --include=".csproj" --include=".props" . 2>/dev/null && echo "FOUND: Swashbuckle (consider built-in OpenAPI for .NET 9+)"
grep -rl "System.Data.SqlClient" --include=".csproj" --include="*.props" . 2>/dev/null && echo "FOUND: System.Data.SqlClient (use Microsoft.Data.SqlClient)"
---echo "=== Code Patterns ==="
grep -rl "class Startup" --include=".cs" . 2>/dev/null && echo "FOUND: Legacy Startup.cs pattern"
grep -rl "Microsoft.Extensions.Http.Polly" --include=".csproj" --include=".props" . 2>/dev/null && echo "FOUND: Deprecated Polly package"
grep -rl "Swashbuckle" --include=".csproj" --include=".props" . 2>/dev/null && echo "FOUND: Swashbuckle (consider built-in OpenAPI for .NET 9+)"
grep -rl "System.Data.SqlClient" --include=".csproj" --include="*.props" . 2>/dev/null && echo "FOUND: System.Data.SqlClient (use Microsoft.Data.SqlClient)"
---Prioritizing Modernization
现代化优先级排序
Not all modernization is equally urgent. Prioritize by impact:
- Security -- vulnerable packages, end-of-life TFMs (no security patches)
- Supportability -- deprecated packages with no upstream maintenance
- Performance -- patterns with significant perf impact (sync-over-async, legacy collections in hot paths)
- Developer experience -- build infrastructure (CPM, analyzers, editorconfig) improves daily workflow
- Code style -- language pattern updates are lowest priority but reduce cognitive load over time
并非所有现代化工作的紧急程度都相同。按影响程度排序:
- 安全 —— 有漏洞的包、已终止支持的TFM(无安全补丁)
- 可维护性 —— 已弃用且无上游维护的包
- 性能 —— 对性能影响显著的模式(同步模拟异步、热点路径中的遗留集合)
- 开发者体验 —— 构建基础设施(CPM、分析器、editorconfig)可改善日常工作流程
- 代码风格 —— 语言模式更新优先级最低,但长期可降低认知负担
What's Next
下一步操作
This skill flags modernization opportunities. For executing upgrades:
- TFM version upgrades and migration paths -- [skill:dotnet-version-upgrade]
- Multi-targeting strategies -- [skill:dotnet-multi-targeting]
- Polyfill packages for cross-version support -- [skill:dotnet-multi-targeting]
- Adding missing build infrastructure -- [skill:dotnet-project-structure], [skill:dotnet-scaffold-project]
- Configuring analyzers -- [skill:dotnet-add-analyzers]
- Adding CI/CD -- [skill:dotnet-add-ci]
本技能仅标记现代化机会。如需执行升级:
- TFM版本升级和迁移路径 —— [skill:dotnet-version-upgrade]
- 多目标框架策略 —— [skill:dotnet-multi-targeting]
- 跨版本支持的兼容填充包 —— [skill:dotnet-multi-targeting]
- 添加缺失的构建基础设施 —— [skill:dotnet-project-structure]、[skill:dotnet-scaffold-project]
- 配置分析器 —— [skill:dotnet-add-analyzers]
- 添加CI/CD —— [skill:dotnet-add-ci]