.NET编码规范
第 6 篇:CSharpier 与dotnet format
—— 让代码格式化自动化
前言
分析器能告诉你"哪里不对",但手动修复 100 条警告是低效的。自动格式化工具就是来解放你的——一条命令,所有代码瞬间统一。
.NET 生态有两款主流自动格式化工具:微软官方的dotnet format和社区派的CSharpier。本文深入对比两者的优劣,帮你做出正确的选择。
一、dotnet format:微软官方的格式化武器
1.1 是什么?
dotnet format是 .NET SDK 自带的工具(.NET 6+),它基于.editorconfig和 Roslyn 分析器的规则,自动修正代码格式。
1.2 基本用法
# 格式化整个解决方案dotnetformat# 格式化特定项目dotnetformat./src/MyProject/MyProject.csproj# 仅分析,不实际修改(生成报告)dotnetformat--verify-no-changes# 包含代码分析器修复dotnetformatstyle--severityinfo# 格式化指定文件dotnetformat--include./src/**/*.cs# 排除特定文件dotnetformat--exclude./**/Migrations/**1.3 它能做什么?
| 功能 | 说明 |
|---|---|
| 空白规范 | 缩进、空格、行尾空白、空行 |
| 命名修正 | 根据.editorconfig中的命名规则自动重命名 |
| 分析器修复 | 自动修复部分 Roslyn 分析器的suggestion级别问题 |
| using 排序 | 按配置排序 using 指令,移除未使用的 |
| 文件编码/换行符 | 按配置统一 |
1.4dotnet format的局限
- 国际化配置:受
.editorconfig规则限制,有些格式化效果取决于配置的完整性 - 不可配置的部分:某些格式决策(如
switch表达式换行位置)不由你决定 - 分析器自动修复有限:只能修复提供了
Code Fix的规则
二、CSharpier:基于 Prettier 哲学的 Opinionated Formatter
2.1 核心理念
CSharpier 的思想来源是前端世界的 Prettier ——“Opinionated Code Formatter”。它的设计哲学是:
“Stop debating code style. Just format it.”
不给太多配置选项,一个风格走天下。这听起来霸道,但恰恰消灭了团队中关于格式的无尽争论。
2.2 安装
命令行安装
# 作为全局工具安装dotnet toolinstall-gcsharpier# 作为项目本地工具(推荐)dotnet new tool-manifest dotnet toolinstallcsharpier可以在扩展中搜索“csharpier”进行安装
2.3 基本用法
# 格式化整个解决方案dotnet csharpier.# 格式化特定文件/目录dotnet csharpier ./src/ dotnet csharpier Program.cs# 仅检查,不修改(CI 场景)dotnet csharpier--check.# 指定多个目录dotnet csharpier ./src/ ./tests/简单配置,可以在选项中csharpier页进行设置
2.4 配置文件:.csharpierrc
在项目根目录创建.csharpierrc.json或.csharpierrc.yaml:
{"printWidth":120,"useTabs":false,"indentSize":4,"endOfLine":"auto","overrides":[{"files":"*.xaml","options":{"parser":"xml","indentSize":2}},{"files":"*.cshtml","options":{"indentSize":2}}]}配置项速查
| 选项 | 默认值 | 说明 |
|---|---|---|
printWidth | 100 | 期望最大行宽(非硬限制) |
useTabs | false | 是否使用制表符缩进 |
indentSize | C#: 4, XML: 2 | 每个缩进级别的空格数 |
endOfLine | "auto" | 换行符风格(auto/lf/crlf) |
overrides | [] | 针对特定文件类型的覆盖规则 |
2.5 与.editorconfig的关系
CSharpier 会读取.editorconfig的部分设置作为回退:
| CSharpier 选项 | 对应的.editorconfig选项 |
|---|---|
useTabs | indent_style |
indentSize | indent_size |
printWidth | max_line_length |
endOfLine | end_of_line |
优先级:.csharpierrc>.editorconfig。
2.6 忽略文件
创建.csharpierignore文件:
# 忽略生成的文件 **/Migrations/ **/obj/ **/bin/ # 忽略特定文件 GeneratedCode.cs三、dotnet formatvs CSharpier —— 终极对比
| 维度 | dotnet format | CSharpier |
|---|---|---|
| 出品方 | 微软官方 | 社区 |
| 安装 | .NET 6+ SDK 自带 | 需安装 dotnet tool |
| 可配置性 | 高(通过 .editorconfig) | 低(Opinionated,少配置) |
| 格式化范围 | 空白、命名、分析器修复 | 空白、换行、整体排版 |
| 命名规范修正 | ✅ 支持 | ❌ 不支持 |
| 分析器联动 | ✅ 自动修复 | ❌ 不涉及 |
| XAML 支持 | 有限 | ✅ 支持 |
| CSHTML/Razor | 有限 | ✅ 通过 overrides 支持 |
| 类型 | 服从规则的 Formatter | 主张风格的 Formatter |
| 适用场景 | 需要精细控制的团队 | 不想争论格式的团队 |
四、选型建议
推荐方案:两者结合使用
- 用 CSharpier 做排版格式化—— 换行、缩进、空格,一键统一
- 用
dotnet format做分析与修复—— 命名修正、代码分析器自动修复
配置文件共存示例
仓库根目录/ ├── .editorconfig ← dotnet format 读取 ├── .csharpierrc.json ← CSharpier 读取 └── .csharpierignore ← CSharpier 忽略列表工作流整合
# 提交前完整格式化流程dotnet csharpier.# 第一步:排版格式化dotnetformatstyle--severityinfo# 第二步:风格修复dotnet build# 第三步:验证分析器规则五、CI/CD 中集成格式化检查
GitHub Actions 示例
name:Format Checkon:[pull_request]jobs:format:runs-on:ubuntu-lateststeps:-uses:actions/checkout@v4-name:Setup .NETuses:actions/setup-dotnet@v4with:dotnet-version:9.0.x-name:Restore toolsrun:dotnet tool restore-name:Check CSharpier formattingrun:dotnet csharpier--check .-name:Check dotnet formatrun:dotnet format style--verify-no-changes--severity info-name:Build with analysisrun:dotnet build--configuration Release-warnaserrorGit Pre-commit Hook(Husky.NET 方式)
// .husky/task-runner.json{"tasks":[{"name":"format","command":"dotnet","args":["csharpier","."]},{"name":"analyze","command":"dotnet","args":["format","style","--severity","info","--include","--verbosity","detailed"]}]}六、常见问题
Q1: CSharpier 把代码改得"我不喜欢"怎么办?
这就是 Opinionated Formatter 的设计理念——放弃个人偏好,接受社区一致风格。如果你真的无法接受某些格式,可以考虑用.csharpierignore排除特定文件,然后用dotnet format单独处理。
Q2: 能不能只格式化变更的文件?
# 利用 Git 获取变更文件列表gitdiff--name-only HEAD|grep'\.cs$'|xargsdotnet csharpier