抛出 ArgumentNullException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/368742/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Throwing ArgumentNullException
提问by Jason Baker
Suppose I have a method that takes an object of some kind as an argument. Now say that if this method is passed a null argument, it's a fatal error and an exception should be thrown. Is it worth it for me to code something like this (keeping in mind this is a trivial example):
假设我有一个将某种对象作为参数的方法。现在说如果这个方法被传递一个空参数,它是一个致命的错误,应该抛出一个异常。我是否值得编写这样的代码(请记住,这是一个微不足道的示例):
void someMethod(SomeClass x)
{
if (x == null){
throw new ArgumentNullException("someMethod received a null argument!");
}
x.doSomething();
}
Or is it safe for me to just rely on it throwing NullException when it calls x.doSomething()?
或者我只依赖它在调用 x.doSomething() 时抛出 NullException 是否安全?
Secondly, suppose that someMethod is a constructor and x won't be used until another method is called. Should I throw the exception immediately or wait until x is needed and throw the exception then?
其次,假设 someMethod 是一个构造函数,并且在调用另一个方法之前不会使用 x。我应该立即抛出异常还是等到需要 x 再抛出异常?
采纳答案by tvanfosson
I prefer the ArgumentNullException
over the NullReferenceException
that not checking the argument would provide. In general, my preference is to always check for nullity before trying to invoke a method on a potentially null object.
我喜欢ArgumentNullException
过NullReferenceException
,不是检查参数将提供。通常,我的偏好是在尝试调用可能为空的对象上的方法之前始终检查空性。
If the method is a constructor, then it would depend on a couple of different factors: is there also a public setter for the property and how likely is it that the object will actually be used. If there is a public setter, then not providing a valid instance via the constructor would be reasonable and should not result in an exception.
如果该方法是一个构造函数,那么它将取决于几个不同的因素:是否还有该属性的公共设置器以及该对象实际被使用的可能性有多大。如果有公共 setter,那么不通过构造函数提供有效实例是合理的,不应导致异常。
If there is no public setter and it is possible to use the containing object without referencing the injected object, you may want to defer the checking/exception until its use is attempted. I would think that the general case, though, would be that injected object is essential to the functioning of the instance and thus an ArgumentNull exception is perfectly reasonable since the instance can't function without it.
如果没有公共 setter 并且可以在不引用注入对象的情况下使用包含对象,则您可能希望推迟检查/异常,直到尝试使用它。不过,我认为一般情况下,注入的对象对于实例的运行至关重要,因此 ArgumentNull 异常是完全合理的,因为没有它,实例就无法运行。
回答by Chris Marisic
I always follow the practice of fail fast. If your method is dependent on X and you understand X might be passed in null, null check it and raise the exception immediately instead of prolonging the point of failure.
我总是遵循快速失败的做法。如果您的方法依赖于 X 并且您知道 X 可能以空值传递,则空检查它并立即引发异常而不是延长故障点。
2016 update:
2016年更新:
Real world example. I strongly recommend the usage of Jetbrains Annotations.
现实世界的例子。我强烈推荐使用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));
Guard statements have been vastly improved with C# 6 providing the nameof
operator.
C# 6 提供了nameof
运算符,Guard 语句得到了极大的改进。
回答by Joel Coehoorn
I prefer the explicit exception, for these reasons:
我更喜欢显式例外,原因如下:
- If the method has more than one SomeClass argument it gives you the opportunity to say which one it is (everything else is available in the call stack).
- What if you do something that may have a side effect before referencing x?
- 如果该方法有多个 SomeClass 参数,则它让您有机会说出它是哪一个(其他所有内容都在调用堆栈中可用)。
- 如果你在引用 x 之前做了一些可能有副作用的事情怎么办?
回答by Aaron Fischer
If you program defensively you should fail fast. So check your inputs and error out at the beginning of your code. You should be nice to your caller and give them the most descriptive error message you can.
如果你进行防御性编程,你应该很快就会失败。因此,请在代码开头检查您的输入和错误。你应该对你的来电者友好,并尽可能给他们最描述性的错误信息。
回答by g .
It is better to throw the ArgumentNullException sooner rather than later. If you throw it, you can provide more helpful information on the problem than a NullReferenceException.
最好尽早抛出 ArgumentNullException。如果你抛出它,你可以提供比 NullReferenceException 更有用的问题信息。
回答by Patrick Desjardins
Do it explicitly if you do not want a Null value. Otherwise, when someone else look at your code, they will think that passing a Null value is acceptable.
Do it as early as you can. This way, you do not propagate the "wrong" behavior of having a Null when it's not supposed to.
如果您不想要 Null 值,请明确执行此操作。否则,当其他人查看您的代码时,他们会认为传递 Null 值是可以接受的。
尽早做。这样,您就不会在不应该传播 Null 时传播“错误”行为。
回答by Szymon Rozga
You should explicitly throw an ArgumentNullException if you are expecting the input to not be null. You might want to write a class called Guard that provides helper methods for this. So your code will be:
如果您希望输入不为空,则应明确抛出 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();
}
The NonNull method would do the nullity check and throw a NullArgumentException with the error message specified in the call.
NonNull 方法将执行无效检查并抛出 NullArgumentException 和调用中指定的错误消息。
回答by Oliver Friedrich
I'd prefer the parameter check with the explicit ArgumentNullException, too.
我也更喜欢使用显式 ArgumentNullException 进行参数检查。
Looking at the metadata:
查看元数据:
//
// 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);
You can see, that the string should be the name of the parameter, that is null, and so give the developer a hint on what is going wrong.
您可以看到,该字符串应该是参数的名称,即空值,因此可以提示开发人员出了什么问题。
回答by Andrew Hare
I agree with the idea of failing fast - however it is wise to know why failing fast is practical. Consider this example:
我同意快速失败的想法 - 但是知道为什么快速失败是可行的是明智的。考虑这个例子:
void someMethod(SomeClass x)
{
x.Property.doSomething();
}
If you rely on the NullReferenceException
to tell you that something was wrong, how will you know what was null? The stack trace will only give you a line number, not which reference was null. In this example x
or x.Property
could both have been null and without failing fast with aggressive checking beforehand, you will not know which it is.
如果您依靠NullReferenceException
告诉您出现问题,您如何知道什么是空值?堆栈跟踪只会给你一个行号,而不是哪个引用为空。在这个例子中,x
或者x.Property
两者都为空并且没有通过事先积极的检查快速失败,你将不知道它是哪个。
回答by andrecarlucci
I'll probably be downvoted for this, but I think completely different.
我可能会因此被否决,但我认为完全不同。
What about following a good practice called "never pass null"and remove the ugly exception checking?
遵循称为“从不传递空值”的良好实践并删除丑陋的异常检查怎么样?
If the parameter is an object, DO NOT PASS NULL. Also, DO NOT RETURN NULL. You can even use the Null object pattern to help with that.
如果参数是一个对象,请勿传递 NULL。另外,不要返回 NULL。您甚至可以使用 Null 对象模式来帮助解决这个问题。
If it's optional, use default values (if your language supports them) or create an overload.
如果它是可选的,请使用默认值(如果您的语言支持它们)或创建一个重载。
Much cleaner than ugly exceptions.
比丑陋的例外要干净得多。