期望返回Null值时应抛出何种标准.NET Exception?
期望结果为Null时的异常处理方案
是否存在对应的标准Exception?
.NET 类库中没有专门对应「期望结果为 Null 但实际返回非 Null」场景的标准异常类型。现有的 Null 相关标准异常(如NullReferenceException、ArgumentNullException)均针对空引用导致的错误场景:
NullReferenceException:尝试解引用空对象引用时抛出ArgumentNullException:向不接受空引用的方法传入空引用时抛出
这些与你遇到的「实体已存在(非Null)需阻止重复创建」的业务场景完全不匹配。
Clean Architecture 场景下的最佳解决方案
1. 使用语义明确的自定义业务异常
你当前自定义的NotNullReferenceException命名容易与标准 Null 异常混淆,建议改为贴合业务语义的名称(如EntityAlreadyExistsException),这样能直观体现异常对应的业务规则,符合 Clean Architecture 中领域层表达业务逻辑的要求。
优化后的自定义异常代码:
public class EntityAlreadyExistsException : Exception { internal EntityAlreadyExistsException(string message) : base(message) { } internal EntityAlreadyExistsException(string message, Exception innerException) : base(message, innerException) { } }
验证方法中替换为该异常:
private async Task ValidateEntityIfExist(EntityModel entityModel, CancellationToken cancellationToken) { Entity entity = await this._repository.GetEntityByIdAsync(entityModel.Id, cancellationToken); if (entity != null) { throw new EntityAlreadyExistsException($"{entityModel} with this id already exists."); } }
2. 遵循分层原则管理业务规则
- 该验证逻辑属于领域层的业务规则,应放在领域服务或实体的验证方法中,而非应用层,确保业务规则集中维护,符合 Clean Architecture 领域层为核心的设计理念。
- 异常抛出后,在应用层或 API 层统一处理:将异常转换为合适的 HTTP 状态码(如 409 Conflict),同时完成日志记录,保证分层职责清晰。
3. 可选方案:返回验证结果对象而非抛出异常
若「实体已存在」属于业务中常见的校验场景(而非意外异常),可考虑返回包含验证结果的对象替代异常抛出,避免用异常控制业务流程。示例代码:
// 定义验证结果类 public class ValidationResult { public bool IsSuccess { get; } public string ErrorMessage { get; } private ValidationResult(bool isSuccess, string errorMessage) { IsSuccess = isSuccess; ErrorMessage = errorMessage; } public static ValidationResult Success() => new ValidationResult(true, null); public static ValidationResult Failure(string errorMessage) => new ValidationResult(false, errorMessage); } // 验证方法返回结果对象 private async Task<ValidationResult> ValidateEntityIfExist(EntityModel entityModel, CancellationToken cancellationToken) { Entity entity = await this._repository.GetEntityByIdAsync(entityModel.Id, cancellationToken); if (entity != null) { return ValidationResult.Failure($"{entityModel} with this id already exists."); } return ValidationResult.Success(); }
内容的提问来源于stack exchange,提问作者Stephen Murumba
相关产品推荐
相关产品推荐

