Throwing ArgumentNullException

C#.NetExceptionException Handling

C# Problem Overview


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()?

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?

C# Solutions


Solution 1 - C#

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.

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.

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.

Solution 2 - C#

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.

2016 update:

Real world example. I strongly recommend the usage of 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.

Solution 3 - C#

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?

Solution 4 - C#

No excuse not to make the check these days. C# has moved on and you can do this very neatly using a discard and a null coalescing operator:

_ = declaringType ?? throw new ArgumentNullException(nameof(declaringType));
_ = methodname ?? throw new ArgumentNullException(nameof(methodName));

Solution 5 - C#

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.

Solution 6 - C#

I'd prefer the parameter check with the explicit ArgumentNullException, too.

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.

Solution 7 - C#

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:

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.

Solution 8 - C#

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.

Solution 9 - C#

  1. 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.

  2. 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.

Solution 10 - C#

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.

Solution 11 - C#

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.

If it's optional, use default values (if your language supports them) or create an overload.

Much cleaner than ugly exceptions.

Solution 12 - C#

I strongly agree with @tvanfosson. Adding to his answer, with .net 6 it’s very easy to throw the ArgumentNullException.

ArgumentNullException.ThrowIfNull(object);

Here’s the official documentation.

Solution 13 - C#

You can use syntax like the following to not just throw an ArgumentNullException but have that exception name the parameter as part of its error text as well. E.g.;

void SomeMethod(SomeObject someObject)
{
    Throw.IfArgNull(() => someObject);
    //... do more stuff
}

The class used to raise the exception is;

public static class Throw
{
    public static void IfArgNull<T>(Expression<Func<T>> arg)
    {
        if (arg == null)
        {
            throw new ArgumentNullException(nameof(arg), "There is no expression with which to test the object's value.");
        }

        // get the variable name of the argument
        MemberExpression metaData = arg.Body as MemberExpression;
        if (metaData == null)
        {
            throw new ArgumentException("Unable to retrieve the name of the object being tested.", nameof(arg));
        }

        // can the data type be null at all
        string argName = metaData.Member.Name;
        Type type = typeof(T);
        if (type.IsValueType && Nullable.GetUnderlyingType(type) == null)
        {
            throw new ArgumentException("The expression does not specify a nullible type.", argName);
        }

        // get the value and check for null
        if (arg.Compile()() == null)
        {
            throw new ArgumentNullException(argName);
        }
    }
}

Solution 14 - C#

All code examples use error prone IF clause, where one use equal operator ==.

What happen, if type override == ?

On C# 7 and greater, use constant pattern matching.

example:

if (something is null) 
{
	throw new ArgumentNullException(nameof(something), "Can't be null.");
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJason BakerView Question on Stackoverflow
Solution 1 - C#tvanfossonView Answer on Stackoverflow
Solution 2 - C#Chris MarisicView Answer on Stackoverflow
Solution 3 - C#Joel CoehoornView Answer on Stackoverflow
Solution 4 - C#AndyWarbyView Answer on Stackoverflow
Solution 5 - C#Andrew HareView Answer on Stackoverflow
Solution 6 - C#Oliver FriedrichView Answer on Stackoverflow
Solution 7 - C#Szymon RozgaView Answer on Stackoverflow
Solution 8 - C#g .View Answer on Stackoverflow
Solution 9 - C#Patrick DesjardinsView Answer on Stackoverflow
Solution 10 - C#Aaron FischerView Answer on Stackoverflow
Solution 11 - C#andrecarlucciView Answer on Stackoverflow
Solution 12 - C#vivek nunaView Answer on Stackoverflow
Solution 13 - C#DiskJunkyView Answer on Stackoverflow
Solution 14 - C#Pekka YlönenView Answer on Stackoverflow