当参数对象的必需属性为空时,应抛出哪个异常

本文关键字:异常 对象 参数 属性 | 更新日期: 2023-09-27 18:01:29

我使用参数对象来封装传递给业务规则的参数。规则是使用上下文参数创建的,然后可以修改上下文参数,然后在稍后的时间执行规则。该对象的某些属性是必需的,否则该方法将抛出一个NullReferenceException。但是,如果抛出一个ArgumentNullException,就会得到一个警告,说参数名与我的一个参数不匹配。对于这种情况,什么是合适的例外呢?

public class GetAttributes : BusinessRuleBase 
{
    private readonly IGetAttributesContext _context;

    public GetAttributes(IGetAttributesContext context)
    {
        _context = context;
    }
    public override void Execute()
    {
        if (_context.AttributeModel == null)
        {
            //Exception would be thrown here
        }
        _context.Attributes = _context.AttributeModel
                                      .DoSomething(_context.EntityType);
    }
}

当参数对象的必需属性为空时,应抛出哪个异常

如果您正在使用代码契约,并且您愿意公开暴露HasAttributeModel属性,我建议

Contract.Requires(this.HasAttributeModel);

否则,您应该在这里抛出派生自InvalidOperationException的自定义异常。给定对象的当前状态,您尝试执行的方法无效。来自文档:

当方法调用对对象的当前状态无效时引发的异常。

你的自定义消息应该说实例的AttributeModelnull

更大的问题是,为什么你允许你的实例处于一种状态,当对象处于无效状态时,一个方法可以被调用?如果可以的话,你应该避免这种情况。例如,为什么GetAttributes不检查context.AttributeModel不是null ?可以是

Contract.Requires(context.AttributeModel != null);

作为此方法的先决条件。然而,这里有一些危险,如果有人保留对参数context的引用的动态引用,他们可能会破坏状态,因为您通过私有变量_context维护引用。注意这一点,尽量避免。

如果你认为有人可能想要捕获这个特殊的异常,并以不同于典型异常的方式处理它,那么编写你自己的异常类。

理想情况下,您可以通过在(命名不佳的)GetAttributes方法中检查此属性来获得快速故障行为。在这种情况下,如果您没有使用自己的自定义异常类型,我会抛出ArgumentException

如果早期检查此属性没有意义,并且您仍然希望使用系统异常类型,那么Jason是正确的:使用InvalidOperationException

抛出带有自定义描述的NullReferenceException,或者创建自己的自定义异常

InvalidArgumentException表示参数无效,但在您的情况下没有参数,并且无效或有效的参数必须不为null。

您应该使用您的自定义异常来确保您真正捕获到您的异常,而不是系统生成的异常。