dotnet-modernize

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

dotnet-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
<TargetFramework>
in
.csproj
files (or
Directory.Build.props
):
Current TFMStatusRecommendation
net8.0
LTS -- supported until Nov 2026Plan upgrade to
net10.0
(LTS)
net9.0
STS -- support ends May 2026Upgrade to
net10.0
promptly
net7.0
End of lifeUpgrade immediately
net6.0
End of lifeUpgrade immediately
net5.0
or lower
End of lifeUpgrade immediately
netstandard2.0/2.1
Supported (library compat)Keep if multi-targeting for broad reach
netcoreapp3.1
End of lifeUpgrade immediately
.NET Framework 4.x
LegacyEvaluate migration feasibility
To scan all projects:
bash
undefined
检查
.csproj
文件(或
Directory.Build.props
)中的
<TargetFramework>
当前TFM状态建议
net8.0
长期支持版(LTS)——支持至2026年11月计划升级至
net10.0
(LTS)
net9.0
标准支持版(STS)——支持至2026年5月及时升级至
net10.0
net7.0
已终止支持立即升级
net6.0
已终止支持立即升级
net5.0
及更低版本
已终止支持立即升级
netstandard2.0/2.1
受支持(库兼容性)若需多目标框架以覆盖广泛场景则保留
netcoreapp3.1
已终止支持立即升级
.NET Framework 4.x
遗留版本评估迁移可行性
扫描所有项目的命令:
bash
undefined

Find 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
Directory.Packages.props
(or individual
.csproj
files) for packages that have been superseded:
Deprecated PackageReplacementSince
Microsoft.Extensions.Http.Polly
Microsoft.Extensions.Http.Resilience
.NET 8
Newtonsoft.Json
(new projects)
System.Text.Json
.NET Core 3.0+
Microsoft.AspNetCore.Mvc.NewtonsoftJson
Built-in STJ.NET Core 3.0+
Swashbuckle.AspNetCore
Built-in OpenAPI (
Microsoft.AspNetCore.OpenApi
) for document generation; keep Swashbuckle if using Swagger UI, filters, or codegen
.NET 9
NSwag.AspNetCore
Built-in OpenAPI for document generation; keep NSwag if using client generation or Swagger UI features.NET 9
Microsoft.Extensions.Logging.Log4Net.AspNetCore
Built-in logging +
Serilog
or
OpenTelemetry
.NET Core 2.0+
Microsoft.AspNetCore.Authentication.JwtBearer
(explicit NuGet package)
Remove explicit PackageReference — included in
Microsoft.AspNetCore.App
shared framework
.NET Core 3.0+
System.Data.SqlClient
Microsoft.Data.SqlClient
.NET Core 3.0+
Microsoft.Azure.Storage.*
Azure.Storage.*
2020+
WindowsAzure.Storage
Azure.Storage.Blobs
/
Azure.Storage.Queues
2020+
Microsoft.Azure.ServiceBus
Azure.Messaging.ServiceBus
2020+
Microsoft.Azure.EventHubs
Azure.Messaging.EventHubs
2020+
EntityFramework
(EF6)
Microsoft.EntityFrameworkCore
.NET Core 1.0+
RestSharp
(older versions)
HttpClient
+
System.Text.Json
.NET Core+
AutoMapper
Manual mapping or source-generated mappersPreference
To scan for deprecated packages:
bash
undefined
扫描
Directory.Packages.props
(或单个
.csproj
文件)以找出被替代的包:
已弃用包替代方案起始版本
Microsoft.Extensions.Http.Polly
Microsoft.Extensions.Http.Resilience
.NET 8
Newtonsoft.Json
(新项目)
System.Text.Json
.NET Core 3.0+
Microsoft.AspNetCore.Mvc.NewtonsoftJson
内置STJ.NET Core 3.0+
Swashbuckle.AspNetCore
内置OpenAPI(
Microsoft.AspNetCore.OpenApi
)用于文档生成;若使用Swagger UI、过滤器或代码生成则保留Swashbuckle
.NET 9
NSwag.AspNetCore
内置OpenAPI用于文档生成;若使用客户端生成或Swagger UI功能则保留NSwag.NET 9
Microsoft.Extensions.Logging.Log4Net.AspNetCore
内置日志 +
Serilog
OpenTelemetry
.NET Core 2.0+
Microsoft.AspNetCore.Authentication.JwtBearer
(显式NuGet包)
移除显式PackageReference —— 已包含在
Microsoft.AspNetCore.App
共享框架中
.NET Core 3.0+
System.Data.SqlClient
Microsoft.Data.SqlClient
.NET Core 3.0+
Microsoft.Azure.Storage.*
Azure.Storage.*
2020+
WindowsAzure.Storage
Azure.Storage.Blobs
/
Azure.Storage.Queues
2020+
Microsoft.Azure.ServiceBus
Azure.Messaging.ServiceBus
2020+
Microsoft.Azure.EventHubs
Azure.Messaging.EventHubs
2020+
EntityFramework
(EF6)
Microsoft.EntityFrameworkCore
.NET Core 1.0+
RestSharp
(旧版本)
HttpClient
+
System.Text.Json
.NET Core+
AutoMapper
手动映射或源生成映射器按需选择
扫描已弃用包的命令:
bash
undefined

List 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

**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

**关于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:
File.ReadAllText
,
Stream.Read
,
HttpClient
without
Async
suffix.
Modern: Use
async
variants --
File.ReadAllTextAsync
,
Stream.ReadAsync
,
await httpClient.GetAsync()
.
标记点:
File.ReadAllText
Stream.Read
、不带
Async
后缀的
HttpClient
方法。
现代化方案: 使用异步变体 ——
File.ReadAllTextAsync
Stream.ReadAsync
await httpClient.GetAsync()

String Concatenation in Hot Paths

热点路径中的字符串拼接

Flag: String concatenation (
+
) or
String.Format
in logging, loops.
Modern: Use string interpolation with
LoggerMessage
source generators, or
StringBuilder
.
标记点: 日志、循环中使用字符串拼接(
+
)或
String.Format
现代化方案: 使用
LoggerMessage
源生成器的字符串插值,或
StringBuilder

Legacy Collection Patterns

遗留集合模式

Flag:
Hashtable
,
ArrayList
, non-generic collections.
Modern:
Dictionary<TKey, TValue>
,
List<T>
, generic collections.
标记点:
Hashtable
ArrayList
、非泛型集合。
现代化方案:
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:
MissingCheckRecommendation
Central Package ManagementNo
Directory.Packages.props
See [skill:dotnet-project-structure]
Directory.Build.propsProperties scattered across
.csproj
files
Centralize shared properties
.editorconfigNo
.editorconfig
at repo root
See [skill:dotnet-project-structure]
global.jsonNo SDK pinningAdd for reproducible builds
NuGet auditNo
NuGetAudit
property
Enable in
Directory.Build.props
Lock filesNo
RestorePackagesWithLockFile
Enable for deterministic restores
Package source mappingNo
packageSourceMapping
in
nuget.config
Add for supply-chain security
AnalyzersNo
AnalysisLevel
or
EnforceCodeStyleInBuild
See [skill:dotnet-add-analyzers]
SourceLinkNo SourceLink package referenceAdd for debugger source navigation
Nullable reference types
<Nullable>
not enabled
Enable globally
.slnxStill using
.sln
with .NET 9+ SDK
Migrate with
dotnet sln migrate

检查是否缺少推荐的构建基础设施:
缺失项检查方式建议
中央包管理(Central Package Management)
Directory.Packages.props
查看 [skill:dotnet-project-structure]
Directory.Build.props属性分散在多个
.csproj
文件中
集中共享属性
.editorconfig仓库根目录无
.editorconfig
查看 [skill:dotnet-project-structure]
global.json未固定SDK版本添加以实现可复现构建
NuGet审计
NuGetAudit
属性
Directory.Build.props
中启用
锁定文件
RestorePackagesWithLockFile
启用以实现确定性还原
包源映射
nuget.config
中无
packageSourceMapping
添加以提升供应链安全性
分析器
AnalysisLevel
EnforceCodeStyleInBuild
查看 [skill:dotnet-add-analyzers]
SourceLink无SourceLink包引用添加以支持调试器源码导航
可空引用类型未启用
<Nullable>
全局启用
.slnx.NET 9+ SDK仍使用
.sln
使用
dotnet sln migrate
迁移

5. Deprecated C# Language Patterns

5. 已弃用的C#语言模式

Old PatternModern ReplacementLanguage Version
switch
statement with
case
switch
expression
C# 8
null != x
/
x != null
checks
x is not null
C# 9
new ClassName()
with obvious type
Target-typed
new()
C# 9
Block-scoped namespacesFile-scoped namespacesC# 10
record class
explicit constructor
record
with positional parameters
C# 10
Manual string concatenation for multi-lineRaw string literals (
"""..."""
)
C# 11
Explicit interface dispatch for
INumber<T>
Generic math interfacesC# 11
[Flags]
enum manual checks
Improved enum pattern matchingC# 11+
Lambda without natural typeNatural function typesC# 10+
ValueTask
manual wrapping
Task
/
ValueTask
with
ConfigureAwait
patterns
C# all
Primary constructor classes (manual)Primary constructors on
class
/
struct
C# 12
Multiple
if
/
else if
type checks
switch
on type with list patterns
C# 11+
params T[]
params ReadOnlySpan<T>
,
params
collections
C# 13
Lock with
object
System.Threading.Lock
C# 13

旧模式现代化替代方案语言版本
case
switch
语句
switch
表达式
C# 8
null != x
/
x != null
检查
x is not null
C# 9
显式类型的
new ClassName()
目标类型
new()
C# 9
块级命名空间文件级命名空间C# 10
record class
显式构造函数
带位置参数的
record
C# 10
手动拼接多行字符串原始字符串字面量(
"""..."""
C# 11
INumber<T>
显式接口调度
泛型数学接口C# 11
[Flags]
枚举手动检查
改进的枚举模式匹配C# 11+
无自然类型的Lambda表达式自然函数类型C# 10+
手动包装
ValueTask
ConfigureAwait
模式的
Task
/
ValueTask
所有C#版本
手动实现主构造函数的类
class
/
struct
的主构造函数
C# 12
多个
if
/
else if
类型检查
基于类型和列表模式的
switch
C# 11+
params T[]
params ReadOnlySpan<T>
params
集合
C# 13
使用
object
的Lock
System.Threading.Lock
C# 13

6. Security and Compliance

6. 安全与合规

IssueDetectionFix
Known vulnerabilities
dotnet list package --vulnerable
Update affected packages
Deprecated packages
dotnet list package --deprecated
Replace with successors
Outdated packages
dotnet list package --outdated
Evaluate updates
Missing HTTPS redirectionNo
app.UseHttpsRedirection()
Add to pipeline
Missing HSTSNo
app.UseHsts()
Add for production
Hardcoded secretsConnection strings in
appsettings.json
Use User Secrets or Key Vault
bash
undefined
问题检测方式修复方案
已知漏洞
dotnet list package --vulnerable
更新受影响的包
已弃用包
dotnet list package --deprecated
替换为继任包
过时包
dotnet list package --outdated
评估更新必要性
缺失HTTPS重定向
app.UseHttpsRedirection()
添加到管道中
缺失HSTS
app.UseHsts()
生产环境添加
硬编码密钥
appsettings.json
中包含连接字符串
使用用户密钥或密钥保管库
bash
undefined

Run 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
undefined

1. 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:
  1. Security -- vulnerable packages, end-of-life TFMs (no security patches)
  2. Supportability -- deprecated packages with no upstream maintenance
  3. Performance -- patterns with significant perf impact (sync-over-async, legacy collections in hot paths)
  4. Developer experience -- build infrastructure (CPM, analyzers, editorconfig) improves daily workflow
  5. Code style -- language pattern updates are lowest priority but reduce cognitive load over time

并非所有现代化工作的紧急程度都相同。按影响程度排序:
  1. 安全 —— 有漏洞的包、已终止支持的TFM(无安全补丁)
  2. 可维护性 —— 已弃用且无上游维护的包
  3. 性能 —— 对性能影响显著的模式(同步模拟异步、热点路径中的遗留集合)
  4. 开发者体验 —— 构建基础设施(CPM、分析器、editorconfig)可改善日常工作流程
  5. 代码风格 —— 语言模式更新优先级最低,但长期可降低认知负担

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]

References

参考资料