When you’re writing code it is good practice to be defensive. There is a movement in coding styles to try and reduce the dreaded null reference exception but currently it can still happen.

Do how do we solve this?

Defensive coding

When you have a method with parameters the parameters need to be checked before being dereferenced. This is to check that they are actually a “thing” that can be used. Otherwise if a null value is passed in then unexpected behaviour will happen.

We do this by checking to see if the parameter is equal to null or not.

static void TestMyArgumentsClassic(Poco poco)
{
    if (poco == null)
    {
        throw new ArgumentNullException(nameof(poco));
    }
}

This code is fine and I’ve written and seen it quite a bit over the years. On it’s own the single check is fine, but when there are a number of parameters to the method it can get to the point where the parameter validation is more code than the functionality!

Reduce the line count

We can reduce the line count by moving all of the above onto one line.

static void TestMyArgumentsClassic(Poco poco)
{
    if (poco == null) { throw new ArgumentNullException(nameof(poco)); }
}

This is ok. Personally not really a fan, but if there are a number of parameters then it’s clear what it is trying to do. It can get a bit confusing when developers remove the braces. This I am not a fan of.

static void TestMyArgumentsClassic(Poco poco)
{
    if (poco == null) throw new ArgumentNullException(nameof(poco)); 
}

The null-coalescing operator to the rescue

The null-coalescing operator has been around for a little while and become a staple in the C# language very quickly. I’ve seen over the years certain constructs arrive in the language but ?? is one of the easier ones to understand and adopt.

It is often used in constructors to test constructor parameters. This can be used to catch instantiation issues early. It allows us to make sure the instance of the class is in a happy state before you try and use it.

public class Poco
{
    private readonly Settings _settings;

    public Poco(Settings settings)
    {
        _settings = settings ?? throw new ArgumentNullException(nameof(settings));
    }
}

The above checks that the parameter passed to the constructor is not null. If it is not null it will assign it to a private variable, otherwise throw an exception.

This construct is ideal for constructors, but it doesn’t help methods. This only works because you are taking the parameter, checking that it is not null, and then assigning it to the private variable.

Discards to the rescue

Another modern C# language feature is the Discards feature.

But what is a discard?

Starting with C# 7.0, C# supports discards, which are temporary, dummy variables that are intentionally unused in application code. Discards are equivalent to unassigned variables; they do not have a value - quote from link

Discards could be the subject of a whole blog post by itself but as you can tell from the link above it is used as a dummy variable with no value. I then saw recently some source code which was using a discard to test method parameters using the null-coalescing operator and thought it was pretty cool. If I can remember where I saw it I will add the link. Found the example, thanks MiniProfiler!

Using Discards and the null-coalescing operator to check method parameters

Here is the above example using discards and null-coalescing operator:

static void TestMyArgumentsNew(Poco poco)
{
    _ = poco ?? throw new ArgumentNullException(nameof(poco));
}

The parameter poco is checked for null but no additional infrastructure or local variables have been used. It’s clean, to the point and has no braces; everyone wins! If the parameter has a value then the code can continue to use it as expected, otherwise an exception will be thrown.

Limitations

Obviously there is some additional work when checking types such as strings etc, but this can be worked around.

A simple extension method can be used so the consuming code is consistent and maintainable.

static void TestMyArgumentsNew(Poco poco, string value)
{
    _ = poco ?? throw new ArgumentNullException(nameof(poco));
    _ = value.Valid() ?? throw new ArgumentNullException(nameof(value));
}

And the extension method looks like this …

public static class StringCheckingExtensions
{
    public static object Valid(this string value)
    {
        return !string.IsNullOrWhiteSpace(value) ? value : null;
    }
}

Conclusion

In this post we have reviewed the different ways of parameter checking for method parameters. We’ve looked at different ways of formatting the null check to try and improve readability. Finally we have looked at using the null-coalescing operator and the discard feature in C# to allow for a simple parameter check.

Any questions/comments then please contact me on Twitter @WestDiscGolf