中文注释规范
在生成、修改、重构或评审 C#/.NET 代码时,按当前任务范围补全或检查准确的简体中文 XML 文档注释。注释工作不得改变业务逻辑、公开契约、成员签名或运行时行为。
工作范围
- 用户明确指定文件或目录时,只处理指定范围;必要的接口、抽象基类和直接继承成员可以作为阅读上下文。
- 用户没有指定路径时,优先处理当前 Git 改动中的 C# 文件。
- 没有明确文件范围且当前没有可用改动时,先询问范围,不默认扫描或修改整个仓库。
- 用户要求“审查”“检查”或“报告问题”时只输出问题、位置和建议,不修改文件。
- 用户要求补全、修复或实现时,只修改注释和完成任务所必需的文档内容。
注释对象
按当前范围检查并处理以下对象:
- 类型:class、interface、abstract class、static class、record、struct、enum、delegate、Controller、ApplicationService、Repository、DTO、Entity 和 Options。
- 构造函数、具名方法、扩展方法、属性、索引器、事件。
- public、protected、internal、private、static、实例、异步、泛型成员。
- 字段、
const、readonly、static readonly、缓存键、配置键、权限名、Header、Claim、正则表达式、超时和重试参数。 - 枚举类型及每个枚举成员。
本地函数不强制使用 XML 注释;逻辑复杂时使用简短普通注释说明原因或关键步骤。
写作要求
- 使用简体中文,准确、简洁、专业;说明业务用途、约束、输入输出、副作用或设计原因,不只翻译成员名称。
- 不因访问级别、
static、异步或泛型而省略注释。 <summary>说明用途和业务语义;<param>说明含义、格式、单位、范围或空值规则;<typeparam>说明泛型参数职责和约束。- 非
void、Task、ValueTask方法补充<returns>。构造函数、void、Task和ValueTask方法不添加<returns>。 Task和ValueTask说明异步操作;Task<T>和ValueTask<T>说明最终返回结果。- 返回
bool时说明true和false的含义;可空返回值说明返回null的条件。 - 只记录调用方需要关注且代码明确抛出或传播的
<exception>;事务、缓存、线程安全、幂等、性能、权限和副作用按需放入<remarks>。 <example>仅用于复杂或容易误用的公共 API。- 字段、常量和键值说明作用范围、生命周期、默认值、边界以及
true/false的业务含义;禁止只写“缓存键”“用户 ID”等重复名称。
继承和实现
接口实现、显式接口实现、抽象成员实现、override、接口属性、索引器和事件,在上游契约已有有效注释时优先使用:
/// <inheritdoc />
实现存在额外行为时,只追加差异:
/// <inheritdoc />
/// <remarks>
/// 查询优先读取缓存,未命中时访问数据库并回填缓存。
/// </remarks>
不要在实现类复制接口或基类的 <summary>、<param> 和 <returns>。普通私有方法、静态辅助方法、字段、常量、构造函数和没有可继承契约的新业务方法需要独立注释。
如果当前维护的接口或抽象基类缺少注释,先完善上游契约,再在实现成员使用 <inheritdoc />。
XML、编码和代码边界
- 参数名必须与实际签名完全一致;不要为不存在的参数生成标签。
- 按 XML 文档语法转义文本中的
&、<、>、引号等特殊字符;代码类型、成员和参数优先使用合法的<see cref="..." />。 - 所有文本文件按 UTF-8 读取和写入,保留项目现有换行和格式约定,不把终端乱码当作文件损坏。
- 只在复杂业务规则、非直观算法、并发/锁、重试/幂等、性能优化、兼容性规避或不可删除代码处添加普通方法体注释,不逐行解释显而易见的代码。
- 排除
bin、obj、*.g.cs、*.generated.cs、*.Designer.cs、EF Core Migration、ModelSnapshot、自动生成客户端、代理代码和第三方源码。
完成检查
- 先阅读接口、抽象类和公共契约,确认实现的真实行为。
- 只补当前范围内缺失、错误、重复或过时的注释。
- 检查标签与签名一致、XML 可解析、引用目标合法、异步返回语义准确。
- 查看最终 diff,确认没有业务代码、签名、命名空间或公开 API 变化。
- 无法从代码确认业务语义时,使用谨慎客观的描述或报告问题,不编造规则。