我正在阅读this post,回答者提到他ArgumentNullException
优先于NullReferenceException
。
MSDN提及NullReferenceException
:
尝试取消引用空对象引用时引发的异常。
在ArgumentNullException
they上说:
将空引用(在Visual Basic中为Nothing)传递给不接受它作为有效参数的方法时引发的异常。
回答者似乎说你可以使用。
是否有任何理由或任何情况我应该选择其中一种?
P.S。
我知道这个问题可能是基于意见的。 我想要事实,背景和情况。我对个人偏好并不感兴趣。
答案 0 :(得分:11)
如果您在代码中明确抛出异常,则应选择ArgumentNullException
。
NullReferenceException
:
unsafe
{
int* ptr = null; // Null pointer.
int val = *ptr; // NullReferenceException thrown.
}
最常见的情况是在空引用上调用方法或属性时:
string s = null;
string substring = s.Substring(0, 2); // NullReferenceException thrown.
在大多数情况下,不应在代码中明确抛出NullReferenceException
。
ArgumentNullException
用于检查将空引用作为参数传递的情况,通常是为了防止NullReferenceException
。
static string firstTwo(string s)
{
if (s == null)
{
throw new ArgumentNullException("s");
}
return s.Substring(0, 2); // without the original check, this line would throw a NullReferenceException if s were null.
}
此检查的目的是清楚地让调用者知道传递了null并且不允许null。否则,如果你只是抛出NullReferenceException
,调用者只会看到
对象引用未设置为对象的实例
这个没有意义(使用支票时):
值不能为空。参数名称:s
答案 1 :(得分:3)
NullReferenceException
永远故意按惯例抛出。它标志着无意的预先违规。因此,它几乎总是发出错误信号。该错误发生在抛出异常的代码中。
按惯例,所有Argument*Exception
都应视为错误。其中99%是真正的错误。 1%不是真正的错误,但值得花时间来阻止它们并抛出更有意义的异常类型来维护惯例。
使用NullReferenceException
表示您拒绝传递的参数。 NullReferenceException
表示抛出此异常的代码的程序员发生了错误。
将Argument*Exception
视为运行时提供的失败断言。 {{1}}的意思是“我想到了这个案例,我有意识地拒绝了它。”。
答案 2 :(得分:0)
即使框架扩展方法看起来像是会引发NullReferenceException
,而是抛出ArgumentNullExceptions
:
List<string> list = null;
var results = list.Select(x => x); //ArgumentNullException
从查看代码(并且事先没有知道Select是一种扩展方法)这个应该抛出一个NullReferenceException
...如果框架甚至没有抛出它们在这种情况下,我总是坚持使用ArgumentNullException