NullReferenceException 与 ArgumentNullException
NullReferenceException vs ArgumentNullException
我正在阅读 this post,回答者提到他更喜欢 ArgumentNullException
而不是 NullReferenceException
。
MSDN 提到 NullReferenceException
:
The exception that is thrown when there is an attempt to dereference a null object reference.
在 ArgumentNullException
they 上说:
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method that does not accept it as a valid argument.
回答者好像说你可以用。
有什么理由或任何情况我应该选择一个而不是另一个吗?
P.S.
我知道这个问题可能是基于意见的。 我想要事实、背景和情况。我对个人喜好不感兴趣。
如果您在代码中明确抛出异常,则应选择 ArgumentNullException
。
NullReferenceException
当空引用/指针被取消引用时,CLR 会自动抛出:
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
被抛出,调用者只会看到
Object reference not set to an instance of an object
没有这个意义(使用检查时):
Value cannot be null. Parameter name: s
即使是看起来会抛出 NullReferenceException
而不是抛出 ArgumentNullExceptions
:
的框架扩展方法
List<string> list = null;
var results = list.Select(x => x); //ArgumentNullException
从只看代码(并且事先不知道 Select 是一个扩展方法)这个 应该 抛出一个 NullReferenceException
... 如果在这种情况下框架甚至不会抛出它们,我会一直坚持使用 ArgumentNullException
NullReferenceException
从不 故意按照约定 抛出。它表示无意的预定义违规。因此,它几乎总是表示错误。该错误在引发异常的代码中。
按照惯例,所有 NullReferenceException
都应被视为错误。其中 99% 是真正的错误。 1% 不是真正的错误,但值得花时间来防止它们并抛出更有意义的异常类型以维护约定。
使用Argument*Exception
表示您拒绝传递的参数。 NullReferenceException
表示抛出该异常的代码的程序员出错了
将 NullReferenceException
视为运行时提供的失败断言。 Argument*Exception
表示 "I thought about this case and I consciously reject it.".
我正在阅读 this post,回答者提到他更喜欢 ArgumentNullException
而不是 NullReferenceException
。
MSDN 提到 NullReferenceException
:
The exception that is thrown when there is an attempt to dereference a null object reference.
在 ArgumentNullException
they 上说:
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method that does not accept it as a valid argument.
回答者好像说你可以用。
有什么理由或任何情况我应该选择一个而不是另一个吗?
P.S.
我知道这个问题可能是基于意见的。 我想要事实、背景和情况。我对个人喜好不感兴趣。
如果您在代码中明确抛出异常,则应选择 ArgumentNullException
。
NullReferenceException
当空引用/指针被取消引用时,CLR 会自动抛出:
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
被抛出,调用者只会看到
Object reference not set to an instance of an object
没有这个意义(使用检查时):
Value cannot be null. Parameter name: s
即使是看起来会抛出 NullReferenceException
而不是抛出 ArgumentNullExceptions
:
List<string> list = null;
var results = list.Select(x => x); //ArgumentNullException
从只看代码(并且事先不知道 Select 是一个扩展方法)这个 应该 抛出一个 NullReferenceException
... 如果在这种情况下框架甚至不会抛出它们,我会一直坚持使用 ArgumentNullException
NullReferenceException
从不 故意按照约定 抛出。它表示无意的预定义违规。因此,它几乎总是表示错误。该错误在引发异常的代码中。
按照惯例,所有 NullReferenceException
都应被视为错误。其中 99% 是真正的错误。 1% 不是真正的错误,但值得花时间来防止它们并抛出更有意义的异常类型以维护约定。
使用Argument*Exception
表示您拒绝传递的参数。 NullReferenceException
表示抛出该异常的代码的程序员出错了
将 NullReferenceException
视为运行时提供的失败断言。 Argument*Exception
表示 "I thought about this case and I consciously reject it.".