Which exception should be thrown when a required property of a parameter object is null
I use parameter objects to encapsulate the parameters that are passed to my business rules. The rule is created using a context parameter, which may then be modified, then at a later time the rule is executed. Some of the properties of this object are required, otherwise the method would throw a NullReferenceException
. However, if I throw an ArgumentNullException
, I get a warning saying that the parameter name does not match one of my parameters. What would be the appropriate exception for this situation?
public class GetAtt开发者_JS百科ributes : 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);
}
}
If you are using Code Contracts and you are willing to publicly expose a HasAttributeModel
property, I recommend
Contract.Requires(this.HasAttributeModel);
Otherwise, you should throw a custom exception that derives from InvalidOperationException
here. The method that you are trying to execute is not valid given the object's current state. From the documentation:
The exception that is thrown when a method call is invalid for the object's current state.
Your custom message should say that the instance's AttributeModel
is null
.
The larger question is, why are you allowing your instances to be in a state where a method could be invoked on them while the object is in an invalid state? You should avoid this, if you can. For example, why isn't GetAttributes
checking that context.AttributeModel
is not null
? You could have
Contract.Requires(context.AttributeModel != null);
as a precondition for this method. However, there is some danger here in that if someone retains a live reference to the referrent of the parameter context
, they could destroy the state since you maintain a reference via the private variable _context
. Be aware of this, and avoid it if you can.
If you think someone may want to catch this particular exception and handle it in a different way from typical exceptions, write your own exception class.
Ideally you could get fail-fast behavior by checking this property in the (poorly-named) GetAttributes
method. In that case, if you're not using your own custom exception type, I would throw an ArgumentException
.
If it doesn't make sense to check this property early on, and you still want to use a system exception type, Jason is right: use an InvalidOperationException
.
Throw a NullReferenceException
with your custom description, or create own custom exception.
InvalidArgumentException
says that the argument is invalid, but in your case there is no argument and for beeing invalid or valid it has to be not null.
You should use your custom exceptions to be sure that you really catch your exception, not the system-generated one.
精彩评论