简体   繁体   中英

Which Null Exception to throw?

Consider the following class and method:

public class MyDto
{
    public MyDtoChild Child {get; set;}
}

and

public void ProcessDto(MyDto myDto)
{
    if(myDto == null) throw new ArgumentNullException("myDto");
    this.CheckSomething(myDto.Child.ChildProperty);
}

If called with a MyDto with a null Child left to it's own devices this will throw a NullReferenceException which can be extremely difficult to diagnose in more complex methods.

Typically I throw an ArgumentNullException at the start of the method if myDto is null but what is the appropriate exception to throw if myDto.Children is null? An ArgumentNullException ? A NullReferenceException ? A custom exception?

As mentioned by the previous answers, it should not be an ArgumentNullException since the argument myDTO is not NULL. To me it makes more sense to throw an ArgumentException since the argument passed to the method did not meet the requirements (you expect Children to not be null). Moreover, your situation fits the ArgumentException's description:

ArgumentException is thrown when a method is invoked and at least one of the passed arguments does not meet the parameter specification of the called method.

Definitely not an ArgumentNullException . If you can access the property Children of your myDto, this means that myDto, which is the argument , is not null . Thus, no ArgumentNullException as the myDto itself is not null .

As you suggested you can throw a NullReferenceException and add your own message so you know where this comes from and explain it nicely. This is completely logic because the reference to the property you want to use is null .

As @Silvermind mentioned, the NullReferenceException should not be used. Instead you have other options such as the ArgumentException or the InvalidOperationException . Another option would be to create your own exception-type that derives from the Exception class.

Example:

public class ChildNullException: Exception
{
    public ChildNullException() { }

    public ChildNullException(string message)
        : base(message)
    {
    }

    public ChildNullException(string message, Exception inner)
        : base(message, inner)
    {
    }
}

If the argument is non-null but somehow invalid, you should throw an ArgumentException :

if(myDto == null) throw new ArgumentNullException("myDto");
if(myDto.Child == null) throw new ArgumentException("Property Child must not be null.", "myDto");

Child of your argument is not your argument, so ArgumentNullException is not appropriate here. I think the best way will be to throw NullReferenceException with an explanation message.

From your explanation I see that this is a program logic error, not data problem. You either load child entity before calling this method, and everything works fine, or you don't load child and this logic cannot be executed. So, it makes no sense to throw some custom exception here, because after you fix problem first time, problem will not happen again. Just see stack trace of exception, fix program logic and forget about this case. Use global exception handler for that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM