当前位置:  开发笔记 > 编程语言 > 正文

抛出ArgumentNullException

如何解决《抛出ArgumentNullException》经验,为你挑选了7个好方法。

假设我有一个方法将某种对象作为参数.现在说如果这个方法传递一个null参数,那就是一个致命的错误,应该抛出一个异常.编写这样的代码对我来说是否值得(请记住这是一个简单的例子):

void someMethod(SomeClass x)
{
    if (x == null){
        throw new ArgumentNullException("someMethod received a null argument!");
    }

    x.doSomething();
}

或者,当它调用x.doSomething()时,依赖它抛出NullException是否安全?

其次,假设someMethod是一个构造函数,在调用另一个方法之前不会使用x.我应该立即抛出异常还是等到需要x然后抛出异常?



1> tvanfosson..:

我喜欢ArgumentNullExceptionNullReferenceException,不是检查参数将提供.通常,我的首选是在尝试在潜在的null对象上调用方法之前始终检查null.

如果该方法是构造函数,那么它将取决于几个不同的因素:是否还有该属性的公共setter以及该对象实际使用的可能性.如果有一个公共setter,那么不通过构造函数提供有效的实例是合理的,不应该导致异常.

如果没有公共setter并且可以在不引用注入对象的情况下使用包含对象,则可能需要推迟检查/异常,直到尝试使用它为止.我认为一般情况下,注入的对象对于实例的运行至关重要,因此ArgumentNull异常是完全合理的,因为没有它,实例就无法运行.


是的,这不是一个偏好的问题.ArgumentNullException是正确的,NullReferenceException不是.NullReferenceException用于当访问的空对象时,例如它的字段或属性.

2> Chris Marisi..:

我总是遵循快速失败的做法.如果您的方法依赖于X并且您理解X可能以null传递,则检查它并立即引发异常而不是延长故障点.

2016年更新:

现实世界的例子.我强烈建议使用Jetbrains Annotations.

[Pure]
public static object Call([NotNull] Type declaringType, 
                          [NotNull] string methodName, 
                          [CanBeNull] object instance)
{
    if (declaringType == null) throw new ArgumentNullException(nameof(declaringType));
    if (methodName == null) throw new ArgumentNullException(nameof(methodName));

C#6为nameof操作员提供了大大改进的防护声明.



3> Joel Coehoor..:

出于以下原因,我更喜欢显式异常:

如果该方法具有多个SomeClass参数,则可以让您有机会说出它是哪一个(其他所有内容都在调用堆栈中可用).

如果你在引用x之前做了一些可能有副作用的事情怎么办?



4> Andrew Hare..:

我同意快速失败的想法 - 然而,明智的是,为什么快速失败是切实可行的.考虑这个例子:

void someMethod(SomeClass x)
{       
    x.Property.doSomething();
}

如果你依靠NullReferenceException告诉你出了什么问题,你怎么知道什么是空的?堆栈跟踪只会为您提供行号,而不是哪个引用为空.在这个例子中,x或者x.Property两者都可以为空并且没有事先通过激进检查快速失败,你将不知道它是什么.



5> Oliver Fried..:

我更喜欢使用显式ArgumentNullException进行参数检查.

查看元数据:

 //
    // Summary:
    //     Initializes a new instance of the System.ArgumentNullException class with
    //     the name of the parameter that causes this exception.
    //
    // Parameters:
    //   paramName:
    //     The name of the parameter that caused the exception.
    public ArgumentNullException(string paramName);

你可以看到,字符串应该是参数的名称,即null,因此给开发人员一个关于出错的提示.



6> g ...:

最好早点而不是稍后抛出ArgumentNullException.如果你抛出它,你可以提供有关问题的更多有用信息,而不是NullReferenceException.



7> Szymon Rozga..:

如果您希望输入不为null,则应显式抛出ArgumentNullException.您可能希望编写一个名为Guard的类,为此提供帮助方法.所以你的代码将是:

void someMethod(SomeClass x, SomeClass y)
{
    Guard.NotNull(x,"x","someMethod received a null x argument!");
    Guard.NotNull(y,"y","someMethod received a null y argument!");


    x.doSomething();
    y.doSomething();
}

NonNull方法将执行nullity检查并抛出NullArgumentException,并在调用中指定错误消息.


异常中的堆栈跟踪怎么样?它将包含Guard方法NotNull,它只是噪音,可能会引起混淆.有没有办法避免这种情况?
推荐阅读
ar_wen2402851455
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有