# 1.3 注释规约 --- ## 1. XML 文档注释 - 类注释 ```csharp /// /// 订单服务,提供订单管理相关业务逻辑 /// /// /// 此服务负责: /// - 订单创建、查询、更新、删除 /// - 订单状态流转 /// - 订单金额计算 /// public class OrderService : IOrderService { // ...existing code... } ``` - 接口注释 ```csharp /// /// 订单仓储接口,定义订单数据访问操作 /// public interface IOrderRepository { /// /// 根据订单ID获取订单详情 /// /// 订单ID /// 订单实体,如果不存在返回 null Task GetByIdAsync(int orderId); } ``` - 方法注释 ```csharp /// /// 创建新订单 /// /// 订单创建请求对象 /// 创建成功的订单实体 /// 当 request 为 null 时抛出 /// 当订单数据验证失败时抛出 /// 当库存不足时抛出 /// /// 此方法执行以下步骤: /// 1. 验证请求数据 /// 2. 检查库存 /// 3. 计算订单金额 /// 4. 创建订单记录 /// 5. 发送确认邮件 /// /// /// /// var request = new CreateOrderRequest /// { /// CustomerId = 123, /// Items = new List<OrderItemDto> /// { /// new() { ProductId = 1, Quantity = 2 } /// } /// }; /// var order = await orderService.CreateOrderAsync(request); /// /// public async Task CreateOrderAsync(CreateOrderRequest request) { // ...existing code... } ``` - 属性注释 ```csharp /// /// 获取或设置订单ID /// public int Id { get; set; } /// /// 获取或设置客户ID /// public int CustomerId { get; set; } /// /// 获取或设置订单总金额(含税) /// /// 订单总金额,单位:元 public decimal TotalAmount { get; set; } /// /// 获取或设置订单是否已完成 /// /// /// true 表示订单已完成;否则为 false /// public bool IsCompleted { get; set; } ``` - 枚举注释 ```csharp /// /// 订单状态枚举 /// public enum OrderStatus { /// /// 待处理 /// Pending = 0, /// /// 处理中 /// Processing = 1, /// /// 已完成 /// Completed = 2, /// /// 已取消 /// Cancelled = 3 } ``` - 泛型参数注释 ```csharp /// /// 通用仓储接口 /// /// 实体类型,必须是引用类型 public interface IRepository where T : class { /// /// 根据ID获取实体 /// /// 实体ID /// 实体对象,如果不存在返回 null Task GetByIdAsync(int id); } ``` ## 2. 行内注释使用场景 - 解释复杂业务逻辑 ```csharp public decimal CalculateDiscount(Order order) { // 根据业务规则BR-2023-001: // VIP客户订单金额超过1000元享受9折优惠 // 新客户首单享受95折优惠 // 优惠不可叠加,取最优惠方案 if (order.Customer.IsVip && order.TotalAmount > 1000) { return order.TotalAmount * 0.1m; } if (order.Customer.IsNewCustomer && order.IsFirstOrder) { return order.TotalAmount * 0.05m; } return 0; } ``` - 解释不明显的代码意图 ```csharp public void ProcessOrder(Order order) { // 将订单状态设置为处理中,防止并发处理同一订单 order.Status = OrderStatus.Processing; order.LastModifiedDate = DateTime.UtcNow; // 使用UTC时间避免时区问题 var processStartTime = DateTime.UtcNow; // 临时解决方案:忽略已删除的订单项 // TODO: 后续需要从数据库层面过滤 var activeItems = order.Items.Where(i => !i.IsDeleted).ToList(); } ``` - 标记临时代码或待优化代码 ```csharp public async Task> GetOrdersAsync(int customerId) { // HACK: 临时解决方案,直接加载所有订单 // 性能问题:当订单量大时会导致内存占用过高 // TODO: 实现分页加载 var orders = await _context.Orders .Where(o => o.CustomerId == customerId) .ToListAsync(); return orders; } ``` - 解释算法或公式 ```csharp public decimal CalculateShippingFee(Order order) { // 运费计算公式: // 基础运费 = 10元 // 重量费用 = 总重量 * 2元/kg // 距离费用 = 距离 * 0.5元/km // 如果订单金额超过200元,免运费 if (order.TotalAmount >= 200) { return 0; } var baseFee = 10m; var weightFee = order.TotalWeight * 2m; var distanceFee = order.DeliveryDistance * 0.5m; return baseFee + weightFee + distanceFee; } ``` ## 3. `TODO`、`FIXME`、`HACK`、`NOTE`/`IMPORTANT` 标记使用 - `TODO` - 待实现功能 ```csharp public class OrderService { public async Task CreateOrderAsync(Order order) { await _repository.AddAsync(order); // TODO: 实现订单创建后发送确认邮件 // TODO: 实现库存扣减逻辑 // TODO: 集成支付网关 } // TODO: [张三] 2024-01-15 实现退款功能 public Task RefundOrderAsync(int orderId) { throw new NotImplementedException(); } } ``` - `FIXME` - 已知问题需要修复 ```csharp public async Task> GetOrdersAsync(int pageIndex, int pageSize) { // FIXME: 当pageSize过大时会导致性能问题 // FIXME: 未处理pageIndex为负数的情况 return await _context.Orders .Skip(pageIndex * pageSize) .Take(pageSize) .ToListAsync(); } public decimal CalculateTotal(Order order) { // FIXME: 并发情况下可能导致重复计算 // 需要添加锁机制或使用数据库事务 return order.Items.Sum(i => i.Price * i.Quantity); } ``` - `HACK` - 临时解决方案 ```csharp public async Task ProcessOrderAsync(int orderId) { // HACK: 临时方案,硬编码重试3次 // 应该从配置文件读取重试次数 for (int i = 0; i < 3; i++) { try { await ProcessAsync(orderId); break; } catch (Exception ex) { if (i == 2) { throw; } await Task.Delay(1000); } } } ``` - `NOTE`/`IMPORTANT` - 重要说明 ```csharp public class PaymentService { // NOTE: 此方法会修改订单状态,调用前请确保已获取锁 // IMPORTANT: 必须在事务中调用此方法 public async Task ProcessPaymentAsync(Payment payment) { // ...existing code... } } ``` ## 4. 复杂业务逻辑注释要求 - 业务规则注释 ```csharp public bool CanApplyDiscount(Order order, Customer customer) { // 业务规则 BR-2024-001: 折扣适用条件 // 1. 客户必须是激活状态 // 2. 订单金额必须大于等于100元 // 3. 客户当月订单数量不超过10个 // 4. 产品不在促销黑名单中 if (!customer.IsActive) { return false; } if (order.TotalAmount < 100) { return false; } var monthlyOrderCount = GetMonthlyOrderCount(customer.Id); if (monthlyOrderCount > 10) { return false; } var hasBlacklistedProducts = order.Items.Any(i => IsProductBlacklisted(i.ProductId)); return !hasBlacklistedProducts; } ``` - 状态机转换注释 ```csharp public void UpdateOrderStatus(Order order, OrderStatus newStatus) { // 订单状态转换规则: // Pending -> Processing (允许) // Pending -> Cancelled (允许) // Processing -> Completed (允许) // Processing -> Cancelled (不允许,必须先退款) // Completed -> Refunded (允许,需要走退款流程) // Cancelled -> * (不允许任何转换) var allowedTransitions = new Dictionary> { { OrderStatus.Pending, new List { OrderStatus.Processing, OrderStatus.Cancelled } }, { OrderStatus.Processing, new List { OrderStatus.Completed } }, { OrderStatus.Completed, new List { OrderStatus.Refunded } } }; if (!allowedTransitions.ContainsKey(order.Status) || !allowedTransitions[order.Status].Contains(newStatus)) { throw new InvalidOperationException($"不允许从 {order.Status} 转换到 {newStatus}"); } order.Status = newStatus; } ``` - 复杂计算注释 ```csharp public decimal CalculateCommission(Order order, Salesperson salesperson) { // 佣金计算规则(2024年Q1版本): // // 基础佣金率: // - 初级销售:订单金额的 3% // - 中级销售:订单金额的 5% // - 高级销售:订单金额的 8% // // 阶梯奖励(累加): // - 月度销售额超过 10万,额外 +1% // - 月度销售额超过 50万,额外 +2% // - 月度销售额超过100万,额外 +3% // // 特殊产品加成: // - 高端产品类别,佣金率 *1.5 var baseRate = salesperson.Level switch { SalesLevel.Junior => 0.03m, SalesLevel.Intermediate => 0.05m, SalesLevel.Senior => 0.08m, _ => 0.03m }; var monthlySales = GetMonthlySales(salesperson.Id); var bonusRate = monthlySales switch { >= 1000000 => 0.03m, >= 500000 => 0.02m, >= 100000 => 0.01m, _ => 0m }; var finalRate = baseRate + bonusRate; var hasHighEndProducts = order.Items.Any(i => i.Product.Category == ProductCategory.HighEnd); if (hasHighEndProducts) { finalRate *= 1.5m; } return order.TotalAmount * finalRate; } ``` ## 5. 注释的维护与更新 - 注释应与代码同步更新 ```csharp // ❌ 错误:注释已过时 // 返回所有订单(实际代码已改为返回激活订单) public List GetOrders() { return _context.Orders .Where(o => o.IsActive) // 代码已修改,但注释未更新 .ToList(); } // ✅ 正确:更新注释 /// /// 获取所有激活状态的订单 /// public List GetActiveOrders() { return _context.Orders .Where(o => o.IsActive) .ToList(); } ``` - 删除无用注释 ```csharp // ❌ 错误:保留已注释的旧代码 public void ProcessOrder(Order order) { // var oldDiscount = order.TotalAmount * 0.05m; // order.DiscountAmount = oldDiscount; // 新的折扣计算逻辑 var newDiscount = CalculateDiscount(order); order.DiscountAmount = newDiscount; } // ✅ 正确:删除已注释代码,使用版本控制系统管理历史 public void ProcessOrder(Order order) { var discount = CalculateDiscount(order); order.DiscountAmount = discount; } ``` - 避免显而易见的注释 ```csharp // ❌ 错误:显而易见的注释 // 设置客户名称 customer.Name = "张三"; // 增加计数器 counter ++; // ✅ 正确:只注释需要解释的内容 // 使用UTC时间避免时区转换问题 order.CreatedDate = DateTime.UtcNow; // 预留30天的订单保留期 var retentionDays = 30; ```