审查和生成遵循Microsoft约定和现代模式的.NET/C#代码。 当审查C#文件、编写.NET代码、重构或用户提及 “C#”, “.NET”, “dotnet”, “csharp”, 或询问.NET项目中的命名约定时使用。 工具:
- 阅读
- 编辑
- 搜索
- 全局搜索
审查.NET代码
应用Microsoft的.NET编码约定和现代C#模式审查或生成代码。
快速参考
命名约定
| 元素 | 风格 | 示例 |
|---|---|---|
| 类,记录 | PascalCase | CustomerService, OrderRecord |
| 接口 | IPascalCase | IRepository, IDisposable |
| 方法 | PascalCase | GetCustomer(), ValidateOrder() |
| 属性 | PascalCase | FirstName, IsActive |
| 公共字段 | PascalCase | MaxRetryCount |
| 参数 | camelCase | customerId, orderDate |
| 局部变量 | camelCase | itemCount, isValid |
| 私有字段 | _camelCase | _connectionString, _logger |
| 常量 | PascalCase | DefaultTimeout, MaxItems |
| 枚举 | PascalCase(单数) | Color.Red, Status.Active |
| 异步方法 | PascalCaseAsync | GetCustomerAsync() |
类型关键字
总是使用语言关键字而不是框架类型:
// 正确
string name;
int count;
bool isActive;
// 避免
String name;
Int32 count;
Boolean isActive;
现代C#模式(C# 10+)
// 文件范围命名空间
namespace MyApp.Services;
// 目标类型新实例
List<Customer> customers = new();
// 集合表达式
string[] items = ["one", "two", "three"];
// 主构造函数
public class Service(ILogger logger, IRepository repo);
// 不可变数据记录
public record CustomerDto(string Name, string Email);
// 原始字符串字面量
var json = """
{ "name": "test" }
""";
审查工作流程
第1步:检查命名
扫描命名违规:
- 类/方法不在PascalCase
- 私有字段没有下划线前缀
- 参数/局部变量不在camelCase
- 异步方法缺少
Async后缀
第2步:检查模式
寻找过时的模式:
String而不是stringnew List<T>()而不是new()或[]- 块范围命名空间
- 手动空检查而不是
?.或??
第3步:检查Async/Await
标记异步反模式:
async void(除了事件处理程序).Result或.Wait()阻塞调用- 图书馆中缺少
ConfigureAwait(false)
第4步:检查异常处理
验证异常模式:
- 捕获
Exception而不是特定类型 - 空catch块
- 不使用
using处理可处置对象
第5步:检查LINQ使用
识别LINQ机会:
- 可以
Select/Where/Any的手动循环 - 多重枚举(应
.ToList())
何时阅读参考文件
- 审查复杂类层次结构
- 需要特定async/await指导
- 审查异常处理模式
- 展示具体改进
- 用户询问"这应该怎么看?"
需要标记的反模式
严重(总是标记)
// 异步void(除了事件处理程序)
public async void ProcessData() { }
// 在异步上阻塞
var result = GetDataAsync().Result;
task.Wait();
// 空catch
try { } catch { }
// 捕获基Exception
catch (Exception ex) { }
重要(审查中标记)
// 匈牙利表示法
int iCount; // 使用:count
string strName; // 使用:name
// 大写字母
const int MAX_SIZE = 100; // 使用:MaxSize
// 系统类型
String name; // 使用:string
代码生成模板
服务类
namespace MyApp.Services;
public class CustomerService(
ILogger<CustomerService> logger,
ICustomerRepository repository)
{
public async Task<Customer?> GetByIdAsync(
int id,
CancellationToken cancellationToken = default)
{
logger.LogDebug("Getting customer {Id}", id);
return await repository.FindByIdAsync(id, cancellationToken);
}
}
记录DTO
namespace MyApp.Models;
public record CustomerDto(
int Id,
string Name,
string Email,
DateOnly CreatedDate);
接口
namespace MyApp.Abstractions;
public interface ICustomerRepository
{
Task<Customer?> FindByIdAsync(int id, CancellationToken ct = default);
Task<IReadOnlyList<Customer>> GetAllAsync(CancellationToken ct = default);
Task AddAsync(Customer customer, CancellationToken ct = default);
}
EditorConfig集成
如果项目有.editorconfig,遵循那些规则进行样式偏好。在建议样式更改之前进行检查。
审查清单
- [ ] 命名遵循约定
- [ ] 使用语言关键字(string, int, bool)
- [ ] 异步方法有Async后缀
- [ ] 没有异步void(除了事件处理程序)
- [ ] 没有阻塞调用(.Result, .Wait())
- [ ] 使用语句处理可处置对象
- [ ] 捕获特定异常类型
- [ ] LINQ在适当的地方使用
- [ ] 应用现代C#特性