用 dotnet/skills 让 AI 写 C# 代码更靠谱
微软昨天(2025年4月)在 GitHub 上开源了一个叫 dotnet/skills 的项目,一天内涨了 2458 个 star。这玩意儿不是新框架,也不是新语言,而是一套给 AI 编码助手准备的提示词模板——专门针对 .NET 和 C# 场景。
说白了,就是告诉 Copilot、Cursor 这类 AI 工具:"怎么写 C# 代码才符合微软官方的最佳实践"。
这个项目解决什么问题?
用过 AI 写 C# 代码的开发者应该都有同感:
- AI 经常生成过时的语法(比如还在用
ArrayList而不是List<T>) - 异步编程时,AI 会忘记加
await或者用Task.Wait()(死锁警告) - 依赖注入的写法不规范,AI 不知道用
AddScoped还是AddTransient - 生成的代码不遵循 .NET 命名规范(方法名大写开头?AI 有时会写成小写)
dotnet/skills 就是给 AI 打补丁——通过精心设计的提示词,告诉 AI 在生成 C# 代码时要遵循什么规则。
核心思路:用规则约束 AI
项目的核心文件是 .github/skills.md(在 GitHub 仓库里),里面写了 AI 在回答 C# 问题时应遵守的规则。比如:
当用户询问 C# 代码时,请遵循 .NET 编码指南,使用最新的语言特性(如记录类型、模式匹配),优先使用异步编程模型,避免使用已弃用的 API。
这不是什么玄学,就是最朴素的提示词工程——把微软官方的编码规范翻译成 AI 能理解的指令。
我看了下仓库里的内容,主要覆盖了这几个方面:
- 语法规范:用 C# 12 的新特性(主构造函数、集合表达式等)
- 异步模式:必须用
await,不用Task.Result或Task.Wait() - 依赖注入:正确使用生命周期(
AddScopedvsAddTransientvsAddSingleton) - 异常处理:用
Result模式而不是裸抛异常 - 性能指南:避免装箱、用
Span<T>处理内存等
完整提示词模板(可直接复制)
我根据项目内容整理了一个可以直接用的提示词模板,你把它放到 AI 工具的系统提示词里就行:
你是一个 C# 代码生成助手。请严格遵循以下规则:
1. 使用 C# 12 或更高版本语法,优先使用:
- 主构造函数(primary constructors)
- 集合表达式(collection expressions)
- 模式匹配(pattern matching)
- 记录类型(record types)
2. 异步编程必须:
- 所有 I/O 操作使用 `await`
- 方法名以 `Async` 结尾
- 避免使用 `Task.Result`、`Task.Wait()`、`Task.Run()`(除非明确需要)
3. 依赖注入:
- 无状态服务用 `AddSingleton`
- 有状态服务用 `AddScoped`(Web 应用默认)
- 轻量级临时服务用 `AddTransient`
4. 命名规范:
- 接口以 `I` 开头
- 方法名 PascalCase
- 私有字段 `_camelCase`
5. 错误处理:
- 优先使用 `Result` 模式(如 `OneOf`、`FluentResults`)而不是裸抛异常
- 只在不可恢复的错误时抛异常
6. 性能:
- 避免装箱(boxing)
- 处理大文件用 `Stream` 而不是 `ReadAllText`
- 复杂字符串拼接用 `StringBuilder`
效果演示:差 Prompt vs 好 Prompt
我拿一个常见场景测试:让 AI 写一个读取文件并处理内容的服务。
❌ 差 Prompt(不给任何规则)
写一个 C# 类,从文件读取 JSON 数据并返回列表。
AI 输出(典型的 "能用但不好" 的代码):
public class DataService
{
public List<Item> GetData(string filePath)
{
var json = File.ReadAllText(filePath);
var items = JsonConvert.DeserializeObject<List<Item>>(json);
return items;
}
}
问题:
- 用
File.ReadAllText阻塞线程(大文件时会卡 UI) - 返回
List<Item>而不是IReadOnlyList<Item>(违反封装原则) - 用
JsonConvert(Newtonsoft.Json)而不是System.Text.Json(微软官方推荐) - 没有异常处理
- 方法名不是异步模式
✅ 好 Prompt(用上面的规则模板)
同样要求,但加上规则后:
public sealed class DataService(ILogger<DataService> logger)
{
public async Task<IReadOnlyList<Item>> GetDataAsync(string filePath, CancellationToken cancellationToken = default)
{
try
{
await using var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true);
var items = await JsonSerializer.DeserializeAsync<List<Item>>(stream, cancellationToken: cancellationToken);
return items?.AsReadOnly() ?? [];
}
catch (FileNotFoundException ex)
{
logger.LogError(ex, "File not found: {FilePath}", filePath);
throw; // 不可恢复的错误
}
catch (JsonException ex)
{
logger.LogError(ex, "Invalid JSON in file: {FilePath}", filePath);
return []; // 可恢复的错误,返回空列表
}
}
}
对比结果:
| 维度 | 差 Prompt | 好 Prompt |
|---|---|---|
| 异步 | 同步阻塞 | 异步流式处理 |
| 序列化 | Newtonsoft.Json | System.Text.Json |
| 异常处理 | 无 | 区分可恢复/不可恢复 |
| 性能 | 全量读入内存 | 流式读取 |
| 可测试性 | 低(硬编码依赖) | 高(主构造函数注入日志) |
| 取消支持 | 无 | 支持 CancellationToken |
差距不是一点点——好 Prompt 生成的代码直接能上生产环境,差的那个只能算 Demo。

为什么这样写有效?
这不是玄学,背后有明确的原理:
AI 模型有 "上下文遗忘" 问题:默认情况下,AI 会倾向于生成最常见的代码模式(比如
File.ReadAllText),因为它训练数据里这种写法出现频率最高。加上明确规则后,相当于给了 AI 一个 "优先级列表"。规则越具体,AI 越听话:"用异步" 太模糊,"所有 I/O 操作必须用
await" 就具体得多。AI 对具体指令的遵守率比抽象原则高 30-50%(这是我个人测试的经验值)。微软官方背书:这套规则直接来自 .NET 团队,比社区里的各种 "最佳实践" 更权威。AI 对 "微软官方" 这个词的权重更高(因为训练数据里官方文档的标注质量更高)。
变体和扩展用法
变体 1:针对特定框架的提示词
如果你在用 ASP.NET Core,可以加几条:
- 控制器方法返回 `IActionResult` 或 `Task<IActionResult>`
- 使用 `[ApiController]` 和路由属性
- 不要在控制器里直接使用 `HttpContext`,通过注入获取
- 使用 `ProblemDetails` 返回错误信息
变体 2:针对单元测试的提示词
- 使用 xUnit 作为测试框架
- 用 `FluentAssertions` 做断言
- 依赖注入用 `WebApplicationFactory<T>` 或 `AutoFixture`
- 测试方法命名格式:`MethodName_Scenario_ExpectedResult`
变体 3:针对性能敏感场景的提示词
- 避免 LINQ 的 `.ToList()` 和 `.Count()` 链式调用
- 用 `ArrayPool<T>` 处理临时数组
- 热点路径用 `unsafe` 代码(需明确标记)
- 使用 `ValueTask` 而不是 `Task`(当结果可能同步返回时)
注意事项
提示词不是万能的:AI 仍然可能犯错,尤其是复杂逻辑。生成代码后一定要 review。
版本兼容性:C# 12 的新特性(如主构造函数)只在 .NET 8+ 可用。如果你的项目是 .NET 6,需要在提示词里指定版本。
不要过度约束:规则太多会让 AI 变得保守,甚至生成不符合上下文的代码。建议控制在 8-10 条。
**这些规则本质是 "最佳实践"**:如果你有特殊需求(比如性能极致优化),可以覆盖这些规则。
总结
dotnet/skills 项目看起来只是几十行提示词,但它解决了一个实际问题:AI 编程助手不懂 .NET 的潜规则。
作为开发者,你不需要等微软更新这个仓库——直接复制上面的模板,根据自己的项目需求调整,就能让 AI 生成的 C# 代码质量提升一个档次。
最后说一句:这个项目刚开源 24 小时,目前只有基础规则。我已经给仓库提了个 PR,建议加上 Blazor 和 MAUI 的专用规则。如果你也有想法,不妨也去贡献一下——毕竟,让 AI 写更好的 C# 代码,对大家都是好事。
