让 GitHub Copilot 更懂你的 .NET 代码风格:一份精简实用的 Copilot Instructions

0 阅读5分钟

前言

使用 GitHub Copilot 开发 .NET 项目时,你是否也遇到过这样的情况:生成的代码基本符合需求,但异步方法、注释、命名和文件编码,总需要再调整一遍?

这些要求单独看都不复杂,但每次对话都重复强调,就有些麻烦了。更合适的做法,是把常用约定整理成一份 Copilot Instructions,让它成为随项目维护的默认指导。

需要先说明:这是一份团队开发模板,不是唯一的 .NET 官方规范。 异步、日志和异常处理参考常见实践;中文注释、文档覆盖范围和文件编码等要求,则需要与团队习惯及项目工具链保持一致。

什么是 Copilot Instructions

Copilot Instructions 是使用自然语言编写的自定义指令,可以描述项目架构、编码风格、依赖限制和验证要求。

在仓库根目录下创建 .github/copilot-instructions.md,粘贴下面的内容:

MyProject/
├── .github/
│   └── copilot-instructions.md
├── src/
├── tests/
├── .editorconfig
└── MyProject.sln

在支持的 Copilot 功能中,这份文件会自动加入当前仓库相关请求的上下文,减少重复说明。

Visual Studio、VS Code、JetBrains IDE 中的 Copilot Chat,以及 GitHub 上的 Copilot cloud agent 和代码审查,都支持仓库级指令。具体能力取决于客户端、插件版本和使用场景。

GitHub Copilot 支持不同类型的自定义说明:docs.github.com/zh/copilot/…

这里讨论的是 Chat、Agent 和代码审查等功能,不是编辑器中边输入边出现的行内代码补全建议。

指令不是强制执行机制,它能帮助 Copilot 理解要求,但不能替代编译器、分析器、测试和人工审查。

一份可以直接复制的精简实用的 Copilot Instructions

下面的模板不绑定特定框架版本,可作为 ASP.NET Core、类库、控制台、WinForms、WPF 等常见 C#/.NET 项目的起点。

其中中文注释等要求属于团队偏好,不需要的条目可以删除。

# .NET Copilot Instructions

## 基本原则
- 遵循项目现有架构,优先复用已有实现
- 只修改与当前任务相关的代码,不顺手重构或格式化无关代码
- 使用项目目标框架和 C# 语言版本支持的语法与 API,以实际生效的构建配置为准
- 命名、格式和编码优先遵循项目明确配置及团队规范;没有明确规定时,修改已有文件保持其风格,新建文件遵循本规范
- 未经任务授权或确认,不引入新的 NuGet 包
- 不手工修改自动生成文件,除非当前任务明确要求且生成流程允许

## 异步规范
- 异步方法通常以 Async 结尾,优先返回 Task 或 Task<T>;实现接口、重写成员及框架约定的入口遵循原有签名
- ASP.NET Core MVC 控制器 Action 的命名遵循项目约定;使用 CreatedAtAction 等 API 时,确保传入名称与实际 Action 名称一致
- ConfigureAwait 的用法遵循项目约定;无明确约定时,不依赖调用上下文的通用类库代码优先使用 ConfigureAwait(false),ASP.NET Core 常规应用代码通常可省略
- await 后需要直接访问 UI 控件时,保留上下文捕获,或显式调度回 UI 线程后再访问
- 不使用 .Result、.Wait()、.GetAwaiter().GetResult() 阻塞异步调用;除事件处理器外,不使用 async void
- 支持取消的异步操作在适用时接收 CancellationToken 并向下传递,该参数通常放在参数列表最后
- I/O 操作优先使用真正的异步 API,不用 Task.Run 包装同步 I/O 来冒充异步

## 注释规范
- 新增注释使用简洁明了的中文,注释末尾不使用中文句号
- 新增或修改的 public/protected 类型和成员按项目文档要求提供 XML 注释,说明用途、参数和返回值(适用时)
- 实现接口或重写成员时,可按项目约定复用已有文档或使用 <inheritdoc/>
- 非直观实现和关键业务约束添加必要注释,重点解释原因,不逐行复述代码
- 修改代码时同步更新相关注释

## 文件编码
- 优先遵循 .editorconfig 和项目工具链的编码要求
- 未规定时,新建文本文件使用 UTF-8;是否带 BOM 按文件类型和工具链确定,JSON 默认使用 UTF-8(无 BOM)
- 无明确配置或转换要求时,修改已有文件保持原有编码和换行风格
- 不对无关文件批量转换编码或换行符

## 命名与代码风格
- 类型、方法、属性、事件和常量使用 PascalCase;参数和局部变量使用 camelCase
- 私有实例字段使用 _camelCase;接口名称以 I 开头;静态字段遵循项目约定
- 启用可空引用类型时正确标注可空性,不滥用 ! 或 null! 抑制警告
- 方法保持单一职责,优先保证可读性,不为满足固定行数机械拆分
- 普通短字符串组合优先使用字符串内插;日志使用结构化消息模板,不使用字符串内插
- 不静默忽略未处理的异常,不用默认值将失败伪装成成功;在 catch 中原样重新抛出当前异常时使用 throw;,不使用 throw ex;

## 验证要求
- 行为变更应在适用时补充或更新测试
- 使用项目已有命令执行相关构建、测试和格式检查,不擅自引入新的验证工具
- 无法执行验证时,明确说明未执行的项目及原因,不声称验证通过

总结

Copilot Instructions 的价值,是把反复口头强调的要求,变成随项目维护的默认指导。

一份实用的 .NET 指令不需要面面俱到:先明确修改边界,再约定异步、注释、编码和命名方式,最后说明如何验证。对于可以自动检查的内容,用 .editorconfig、格式工具、分析器和测试兜底。

指令让 Copilot 更理解团队,工具让结果更可靠。 从一份小而明确的模板开始,再根据项目实际情况持续调整,通常比一开始写出庞大而绝对的规则更有效。