NullReferenceException vs ArgumentNullException

瘦欲@ 提交于 2019-12-08 00:04:02

问题


I was reading this post where the answerer mentioned he prefered ArgumentNullException over NullReferenceException.

MSDN mention that for NullReferenceException:

The exception that is thrown when there is an attempt to dereference a null object reference.

On ArgumentNullException they say:

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.

The answerer seems to say that you can use either.

Is there any reason or any case where I should choose one over the other?

P.S.

I know this question could be opinion based. I want fact, context and situation. I am not interested by personnal preference.


回答1:


If you are explicitly throwing the exception in your code, you should choose ArgumentNullException.

NullReferenceException is thrown automatically by the CLR when a null reference / pointer is dereferenced:

unsafe
{
    int* ptr = null; // Null pointer.
    int val = *ptr; // NullReferenceException thrown.
}

This most commonly happens when method or property is called on a null reference:

string s = null;
string substring = s.Substring(0, 2); // NullReferenceException thrown.

In most cases, NullReferenceException should not be explicitly thrown in code.

ArgumentNullException is used to check for cases when a null reference is passed as a parameter, usually to prevent a 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.
}

The purpose of this check is to clearly let the caller know that null was passed and null is not allowed. Otherwise, if you simply let the NullReferenceException be thrown, the caller would only see

Object reference not set to an instance of an object

which is not as meaningful as this (when using the check):

Value cannot be null. Parameter name: s




回答2:


NullReferenceException is never thrown intentionally by convention. It signals an unintentional precodition violation. Therefore, it almost always signals a bug. The bug is in the code that throws the exception.

All NullReferenceExceptions should be considered bugs by convention. 99% of them are true bugs. 1% are not true bugs but it's worth the time time to prevent them and throw a more meaningful exception type to uphold the convention.

Use Argument*Exception to signal that you reject the argument that was passed. NullReferenceException means that the programmer of the code that throws this exception has made an error.

Treat NullReferenceException as a failing assertion that was provided by the runtime. Argument*Exception means "I thought about this case and I consciously reject it.".




回答3:


Even framework extension methods that look like they would throw a NullReferenceException, instead throw ArgumentNullExceptions:

List<string> list = null;
var results = list.Select(x => x); //ArgumentNullException

From just looking at the code (and without prior knowledge that Select is an extension method) this should throw a NullReferenceException... if the framework doesn't even throw them in this situation, I would always stick to using ArgumentNullException



来源:https://stackoverflow.com/questions/39520241/nullreferenceexception-vs-argumentnullexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!