What is the best way to extend null check?

Viewed 6919

You all do this:

public void Proc(object parameter)
{
    if (parameter == null)
        throw new ArgumentNullException("parameter");

    // Main code.
}

Jon Skeet once mentioned that he sometimes uses the extension to do this check so you can do just:

parameter.ThrowIfNull("parameter");

So I come of with two implementations of this extension and I don't know which one is the best.

First:

internal static void ThrowIfNull<T>(this T o, string paramName) where T : class
{
    if (o == null)
        throw new ArgumentNullException(paramName);
}

Second:

internal static void ThrowIfNull(this object o, string paramName)
{
    if (o == null)
        throw new ArgumentNullException(paramName);
}

What do you think?

7 Answers

As of .NET 6, now we have the static method ThrowIfNull in the System.ArgumentNullException class with the following signature:

ThrowIfNull(object? argument, string? paramName = null);

Therefore, instead of writing:

if (value == null)
{
    throw new System.ArgumentNullException(nameof(value));
}

Now we can simply write:

System.ArgumentNullException.ThrowIfNull(value);

The docs: https://docs.microsoft.com/en-us/dotnet/api/system.argumentnullexception.throwifnull?view=net-6.0


The implementation of this new method takes advantage of the System.Runtime.CompilerServices.CallerArgumentExpressionAttribute attribute to simplify this further, by not requiring the developer to explicitly provide the name of the parameter that's being guarded.

The discussion that ended up introducing this new API can be found here: https://github.com/dotnet/runtime/issues/48573

The PR that introduced it in the .NET 6 code base can be found here: https://github.com/dotnet/runtime/pull/55594

Based on C# 10, I use the ThrowIfNull extension method:

public static class CheckNullArgument
{
    public static T ThrowIfNull<T>(this T argument)
    {
        ArgumentNullException.ThrowIfNull(argument);

        return argument;
    }
}

Usage:

public class UsersController
{
    private readonly IUserService _userService;

    public UsersController(IUserService userService)
    {
        _userService = userService.ThrowIfNull();
    }
}
Related