扔哪个Null Exception?

时间:2014-07-09 07:44:42

标签: c# exception

考虑以下类和方法:

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

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

如果使用MyDto调用并将Child留给它自己的设备,则会抛出NullReferenceException,这在更复杂的方法中很难诊断。

通常,如果ArgumentNullException为null,则在方法的开头抛出myDto但是如果myDto.Children为空,则抛出的适当例外是什么? ArgumentNullException?一个NullReferenceException?自定义异常?

5 个答案:

答案 0 :(得分:5)

如前面的答案所述,它不应​​该是ArgumentNullException,因为参数myDTO不是NULL。 对我来说,抛出ArgumentException更有意义,因为传递给方法的参数不符合要求(您希望Children不为null)。此外,您的情况符合ArgumentException的描述:

  

调用方法时至少抛出一个方法时抛出ArgumentException   传递的参数不符合参数规范   被叫方法。

答案 1 :(得分:4)

绝对不是ArgumentNullException。如果您可以访问myDto的属性Children,这意味着myDto是参数不为空。因此,没有ArgumentNullException作为myDto本身 not null

正如您所建议的那样,您可以抛出NullReferenceException并添加自己的消息,以便了解其来源并妥善解释。这完全是逻辑,因为您要使用的属性的引用 null

正如@Silvermind所提到的,不应该使用NullReferenceException。相反,您还有其他选项,例如ArgumentExceptionInvalidOperationException。另一种选择是创建自己的异常类型,该类型派生自Exception类。

示例:

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

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

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

答案 2 :(得分:4)

如果参数为非null但以某种方式无效,则应抛出ArgumentException

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

答案 3 :(得分:3)

你的论证的孩子不是你的论据,所以ArgumentNullException在这里不合适。我认为最好的方法是向NullReferenceException发送一条解释信息。

答案 4 :(得分:2)

根据您的解释,我发现这是一个程序逻辑错误,而不是数据问题。您可以在调用此方法之前加载子实体,并且一切正常,或者您不加载子级,并且无法执行此逻辑。所以,在这里抛出一些自定义异常是没有意义的,因为在你第一次修复问题之后,问题不会再发生了。只看堆栈跟踪异常,修复程序逻辑并忘记这种情况。为此使用全局异常处理程序。