ArgumentNullException - how to simplify?

Viewed 18848

I've noticed this code crops up a lot in my constructors:

if (someParam == null) throw new ArgumentNullException("someParam");
if (someOtherParam == null) throw new ArgumentNullException("someOtherParam");
...

I have a few constructors where several things are injected and must all be non-null. Can anyone think of a way to streamline this? The only thing I can think of is the following:

public static class ExceptionHelpers
{
   public static void CheckAndThrowArgNullEx(IEnumerable<KeyValuePair<string, object>> parameters)
   {
      foreach(var parameter in parameters)
         if(parameter.Value == null) throw new ArgumentNullException(parameter.Key);
   }
}

However, the usage of that would be something like:

ExceptionHelper.CheckAndThrowArgNullEx(new [] {
    new KeyValuePair<string, object>("someParam", someParam),
    new KeyValuePair<string, object>("someOtherParam", someOtherParam),
    ... });

... which doesn't really help streamline the code. Tuple.Create() instead of KVPs doesn't work because Tuple's GTPs aren't covariant (even though IEnumerable's GTP is). Any ideas?

17 Answers

.NET 6 and beyond

There is a new method in .NET API ArgumentNullException.ThrowIfNull(someParameter).

This method is probably the best option which you can get.

C# 11 (currently as proposal)

Use new Bang Bang operator !! on a parameter to implicit check for null.

public string SomeFunction(Foo foo!!)
{
  // here, foo is already checked for null
  // ArgumentNullException(nameof(foo)) is thrown when foo = null
  return $"Here is {foo.Bar}";
}

TL;DR

The compiler will emit this code for every !! use

if (someArgument is null)
{
  throw new ArgumentNullException(nameof(someArgument));
}

Our SomeFunction will be transformed into

public string SomeFunction(Foo foo!!)
{
  if (foo is null)
  {
    throw new ArgumentNullException(nameof(foo));
  }
  return $"Here is {foo.Bar}";
}

In c# 10 you can just do this:

ArgumentNullException.ThrowIfNull(z);

And you will got this error:

System.ArgumentNullException: Value cannot be null. (Parameter 'z')
   at System.ArgumentNullException.Throw(String paramName)
   at System.ArgumentNullException.ThrowIfNull(Object argument, String paramName)
   at ConsoleApp1.SomeClass.Join(String a, String b)

Under the hood, it use the new CallerArgumentExpression attribure.

In c# 7 can be done like this:

_ = someParam ?? throw new ArgumentNullException(nameof(someParam));

After release optimisation you will get:

if (someParam == null)
    throw new ArgumentNullException(nameof(someParam));

With C# 11 and .NET 6.0 you can do this:

public bool DoSomething(string name)
{
    ArgumentNullException.ThrowIfNull(name);

    // Do your stuff, name is not null
}

ArgumentNullException.ThrowIfNull Method

Related