| name | csharp |
| description | 凡涉及 C# / .NET 项目必须加载并遵循。按项目目标框架(TFM)区分行为与检索关键词;优先 dotnet CLI 与静态分析,必要时可自行 dotnet build / dotnet test / dotnet run 验证。长生命周期测试进程须记录 PID,收尾时随主进程链释放。成功标准以任务为准:通常为零错误编译,需要时含测试通过或运行结果可解释。 |
C# 项目开发 Skill(csharp)
适用于在 C# / .NET 项目中进行需求分析、架构设计、功能开发、重构与调试。
智能体应主动利用文件工具、搜索工具、子代理和网络搜索来完成较复杂的分析与 Debug,而不仅仅是单次编辑。
零、适用范围与强制加载(必读)
- 只要当前任务涉及 C# / .NET(包括但不限于:
.cs、.csproj、.sln、global.json、Directory.Build.props、NuGet、MSBuild、dotnet CLI),必须先完整阅读本 Skill 并按其执行,再结合工作区内的 coding、search、editing 等通用 Skill。
- 阶段变化:若一开始未涉及 C#,在后续步骤(探索仓库、用户补充需求、构建失败等)才明确需要改 C# / 跑
dotnet,在进入该类操作之前须已阅读(或重读)本 Skill。各阶段的具体约定以本文件为准,系统提示词只作列表级引导,不能替代本 Skill 中的分步与铁律。
- 若仓库同时含其他语言,仅 C# 相关子路径/子项目仍适用本 Skill 的 C# 部分约定。
一、铁律(必须无条件遵守)
dotnet build 无错误是常规任务的基线完成条件;若任务明确要求验证测试或运行行为,则还须满足该要求(见下条)。
- 运行与测试:默认以编译 + 静态分析为主,避免无目的长跑。在以下情况可以且应当使用
dotnet test、dotnet run 或等价方式(如测试单个类、筛选 --filter)自行验证:
- 行为/回归仅靠读代码无法可靠判断;
- 修复 Bug 或实现与运行时配置、启动参数、环境相关的逻辑;
- 用户明确要求验证或交付标准包含测试通过。
- 长时间/有副作用的操作(如监听端口的服务、需交互的控制台)应先评估是否可用单元测试或最小复现代替;若必须运行,应使用非交互参数、明确超时,并在回复中说明执行了哪些命令与结论。
- 进程 ID(PID)与释放:凡在测试/调试中启动且会持续运行或可能派生子进程的进程(如
dotnet run、自起 Web/服务、Start-Process、后台作业),智能体必须记录主进程 PID;若存在由本次启动产生的关键子进程,也应记录其 PID 或说明如何随主进程一并结束。在验证结束或会话收尾时,必须跟随本次启动的主进程链释放资源:对仍存活的对应进程执行终止(如 PowerShell Stop-Process -Id <PID>),避免遗留占用端口、句柄或 CPU 的孤儿进程。一次性命令且进程自然退出(如多数 dotnet test、短时 dotnet run 至退出)可在总结中标明「已退出」即可。
- 禁止为「刷存在感」而反复运行;每次运行应有清晰目的,并在收尾时简要记录命令与结果摘要。
二、目标框架(TFM)识别与分版本处理
在修改代码、选 NuGet 版本、上网检索前,应先确定项目面向的 .NET 版本。
1. 如何识别
- 用
Glob 查找 **/*.csproj、必要时 Directory.Build.props / Directory.Build.targets。
- 读取其中
<TargetFramework> 或 <TargetFrameworks>(多目标用 ; 分隔,如 net8.0;net10.0)。
- 可在仓库根执行
dotnet --info 或 dotnet --version 了解当前环境 SDK,与 TFM 对照(SDK 需支持该 TFM)。
2. 分版本时的注意点(技能层)
| 场景 | 做法 |
|---|
| API / 包兼容性 | 查文档或 WebSearch 时带上 TFM(如 net10.0)与年份,避免把仅适用于旧框架的示例照搬。 |
| 多目标项目 | 优先改公共 API,必要时用 #if NET8_0 等条件编译;或针对每个 TFM 分别 dotnet build。 |
| 语言版本 | 从 LangVersion 或 SDK 推断;高版本 C# 特性在低 LangVersion 项目中不得使用,除非同步提升配置并有理由。 |
| 可空引用 / 隐式 usings | 以各 .csproj 中的 Nullable、ImplicitUsings 为准,不引入与项目冲突的全局假定。 |
3. 检索用语建议
- 错误信息 +
csharp + 具体 TFM 或 major 版本(如 net10.0 / .NET 10)。
- Breaking change:优先官方迁移文档与发行说明。
三、可用工具与职责分工
1. 文件与代码操作
- 使用
Read:读取 .cs、.csproj、.sln、配置文件等内容。
- 使用
StrReplace / Write:结构化修改(新增类/方法、重构逻辑、修复 Bug)。
- 使用
Glob:按模式列出 C# 相关文件(如 **/*.cs、**/*.csproj),避免硬编码文件列表。
- 使用
ReadLints:在修改后检查被编辑文件是否存在新的诊断问题,并尽量修复。
2. 代码搜索与理解
- 使用
Grep(rg):
- 精确或正则搜索:类名、方法名、接口、错误消息、日志文本。
- 典型用法:搜索
class <Name>、interface <Name>、MethodName\( 或错误码。
- 通过
glob 或 type=cs 仅在 C# 文件中搜索。
- 使用
SemanticSearch / Glob + Grep:
- 在功能/概念级别查找相关实现。
- 适合单个关键字不足以准确匹配的场景。
3. 终端命令(Shell / exec)
- 始终按 PowerShell 语法构造命令;多命令串联使用
; 而不是 &&。
- 合法典型命令:
- 项目管理:
dotnet new、dotnet sln、dotnet add(项目引用/包)等。
dotnet restore
dotnet build -v normal(推荐默认,用于完整编译输出)
dotnet build -c Release
- 验证:
dotnet test [项目或路径] [--filter ...]、dotnet run [--project ...](在「一、铁律」允许的前提下)
- 不得通过 Shell 调用
grep / rg,优先使用内置 Grep 工具完成搜索。
4. 子代理(Task 工具)
当单次对话难以完成复杂任务(如大规模重构、全仓库架构梳理、复杂调试)时:
- 使用子代理:
subagent_type: "explore":需要在大仓库中系统梳理结构、找调用链、罗列相关文件时使用。
subagent_type: "generalPurpose":需要多轮推理、综合文档/网络信息来设计方案或长流程任务时使用。
- 在
prompt 中明确:
- 目标(例如:“重构所有同步 IO 调用为异步”)。
- 需要返回的结果形式(文件列表、改造建议、TODO 列表等)。
- 是否允许写入(单纯分析用
readonly: true)。
- 子代理若涉及 C#,应在任务说明中写明 仓库 TFM 与约束。
- 并行建议:当需要同时梳理多个目录/多个实现/多处引用点时,可把任务拆成多个子代并行执行;子代默认以“证据收集 + 修改建议”为主,避免多个子代同时编辑同一文件。
子代任务模板(最小化、结果导向)
- Goal: <一句话目标>
- Scope: <路径范围/不允许触碰的文件>
- Output: <需要的输出格式:要点/文件列表/行号/差异对比>
- WriteAllowed: false(默认;若必须写入,按文件分区并行,避免同文件并发)
5. 网络信息(WebSearch / WebFetch)
在以下场景主动使用网络:
- 不确定某个 .NET API / NuGet 包在当前 TFM 下的用法或推荐实践。
- 碰到晦涩异常或编译错误,仓库内代码与注释无法解释原因。
- 需要确认当前年代的最佳实践或重大 Breaking Change。
使用建议:
WebSearch:错误消息 / API 名 + c# + TFM 或 .NET 版本。
WebFetch:对于具体的文档链接(如 learn.microsoft.com、GitHub README)拉取并阅读关键片段。
四、四步闭环(提高编写质量与成功率)
与 coding skill 一致:识别分析问题 → 规划路径 → 代码编写 → 检查验证。C# 场景下具体化为:
1. 识别分析问题 — 发生了什么
- 明确现象:是 Bug、新需求、重构还是配置/依赖问题?复现条件与错误信息(含文件、行号、错误码)完整记录。
- 收集信息:用
Glob / Grep 找到项目入口、相关类/接口、调用链;读 .csproj、*.sln 确认 TFM、依赖与目标。
- 归纳根因:类型不匹配、命名空间缺失、API 变更、还是逻辑/边界问题?先有结论再改,避免盲目改。
2. 规划路径 — 应该如何做
- 列出改动点:要改/新增哪些
.cs、接口、方法?调用方与测试是否要同步改?
- 拆分步骤:大改动拆成小步(如先改接口签名、再改实现、再改调用处),每步都可
dotnet build 验证。
- 选对工具:读代码用
Read,定位用 Grep/Glob,修改用 StrReplace/Write,构建用 dotnet build;需要行为验证时再按需 dotnet test / dotnet run。
3. 代码编写 — 执行
- 先读再改:修改前
Read 目标文件及引用处,保持项目现有命名、异常处理、日志与 DI 风格。
- 小步构建:每完成一小块就
dotnet build,避免一次改很多再一起排错。
- 大文件增量编辑:优先局部修改,避免整文件重写导致误删逻辑;新类/新文件可整体写入。
4. 检查验证 — 闭环检查
- 必做编译:修改后执行
dotnet restore(如有新包)和 dotnet build -v normal,零错误为常规交付底线。
- 按需测试/运行:按「一、铁律」判断是否需要
dotnet test / dotnet run;需要时记录命令与结果。
- 按错误逐个修:根据编译器输出的文件/行号用
Read 查看,用 Grep 找引用与定义,修完再 build,直到满足任务完成条件。
五、推荐工作流(从需求到交付)
- 理解需求 — 解析输入/输出、边界条件、多模块时草拟架构与命名空间。
- 锁定 TFM — 读
csproj / 共享 props,必要时 dotnet --info。
- 全局扫描与代码定位 —
Glob/Grep 找入口、领域层、服务与配置。
- 方案设计 — 规划新增/修改的类与方法;大重构可用子代理
explore 生成分步 TODO。
- 实现 / 修改 —
Read + StrReplace/Write,遵循项目风格与 TFM。
- 编译验证 —
dotnet restore + dotnet build -v normal。
- 可选运行验证 — 按任务需要执行
dotnet test / dotnet run。
- 收尾 — 总结改动、TFM、已执行命令与结果;若未运行测试,可说明原因与用户可选后续命令。
六、调试(Debug)细化流程
1. 编译错误调试
- 步骤:
- 阅读
dotnet build -v normal 输出,记录第一个错误及其上下文(文件、行号、错误码)。
- 使用
Read 查看对应文件和附近代码。
- 如错误与类型/命名空间相关,使用
Grep 搜索相关类型或命名空间定义。
- 无法从仓库内推断时,使用
WebSearch 查询错误码或异常信息,并结合 当前 TFM 理解原因。
- 修改代码后再次
dotnet build,重复直至通过。
2. 逻辑错误(静态分析 + 可选运行)
- 静态分析(始终可做):
- 用
Grep 搜索方法/接口的所有调用点;复杂时用子代理 explore 梳理调用链。
- 检查边界条件、异常处理、并发与共享状态。
- 运行验证(在「一、铁律」允许时):用
dotnet test 或最小复现程序确认行为,避免仅凭猜测改逻辑。
3. 第三方库与 API 问题
- 如果涉及 NuGet 包或外部 API:
- 用
WebSearch + WebFetch 查看官方文档与示例,核对包版本与 TFM 兼容性。
- 对照现有用法,识别是否存在已废弃的 API、默认行为变化、配置缺失等问题。
七、dotnet CLI 速查表(Shell 命令)
所有命令均以工作区根目录或解决方案根目录为基准,注意相对路径。
| 命令 | 说明 |
|---|
dotnet new sln -n <Name> | 创建解决方案 |
dotnet new console -n <Name> | 创建控制台项目 |
dotnet new classlib -n <Name> | 创建类库项目 |
dotnet sln add <projPath> | 将项目加入解决方案 |
dotnet add <projPath> reference <refProj> | 添加项目引用 |
dotnet add <projPath> package <PackageId> [-v <Version>] | 向项目添加 NuGet 包 |
dotnet restore | 还原所有依赖包 |
dotnet build -v normal | Debug 编译并输出详细信息(推荐默认) |
dotnet build -c Release | Release 编译 |
dotnet test [路径] | 运行测试(按需) |
dotnet run [--project <csproj>] | 运行可执行项目(按需) |
NuGet 包搜索(如本地 SDK 支持):
dotnet package search <关键词> [--take 10] [--exact-match] [--prerelease] [--source <url>] [--format json]
八、注意事项与最佳实践
- 路径约定:优先使用相对工作区的路径;在命令和代码中避免硬编码绝对路径。
- 批量修改:大规模重构前,先用
Glob / Grep 列出受影响文件,再逐个 Read / 编辑。
- 输出截断:对于可能产生大量构建/测试输出的操作,仅关注关键失败信息并在必要时提示用户本地完整查看。
- 风格一致性:参照项目中已有 C# 代码风格(命名、格式、日志、异常处理),避免在同一项目内引入多套风格。
- 证据链:能编译不等于逻辑正确;对关键路径在条件允许时用测试或短时运行佐证。
- PID 与清理:与「一、铁律」一致;凡手动拉起长生命周期进程,回复中应能列出曾记录的 PID 及是否已清理完毕。
九、智能体总结要求
- 完成任务后,应简要总结:
- 修改或新增了哪些核心类/方法。
- 目标 TFM 及是否做了版本相关处理。
- 如何解决了主要编译错误或逻辑问题。
- 实际执行过的命令(如
dotnet build、dotnet test、dotnet run)及结果摘要;若未运行,说明原因即可。
- 若曾启动需持续运行的进程:列出记录过的 PID 及是否已随主进程链释放(或说明单次运行已自行退出)。