56

For example, you usually don't want parameters in a constructor to be null, so it's very normal to see some thing like

if (someArg == null)
{
    throw new ArgumentNullException(nameof(someArg));
}

if (otherArg == null)
{
    throw new ArgumentNullException(nameof(otherArg));
}

It does clutter the code a bit.

Is there any way to check an argument of a list of arguments better than this?

Something like "check all of the arguments and throw an ArgumentNullException if any of them is null and that provides you with the arguments that were null.

By the way, regarding duplicate question claims, this is not about marking arguments with attributes or something that is built-in, but what some call it Guard Clauses to guarantee that an object receives initialized dependencies.

SuperJMN
  • 13,110
  • 16
  • 86
  • 185
  • 2
    possible duplicate of [Mark parameters as NOT nullable in C#/.NET?](http://stackoverflow.com/questions/291340/mark-parameters-as-not-nullable-in-c-net) – Alex Shesterov Mar 21 '15 at 16:12
  • 1
    maybe put them all in an object array and iterate over them using a foreach loop? you need something like that? – JoJo Mar 21 '15 at 16:15
  • We usually check our parameters at the beginning of the method like your code snippet. Not only for null, also for other business logic behaviors. I don't see any problem with that as long as you don't have too many parameters. At least you can read the requirements of your method easily. – Andre Mar 21 '15 at 16:19
  • 1
    @JoJo That's an awful idea. You don't want to make a method that is intended to take a very specific number and type of objects as parameters take an unknown number of objects of unknown types just for the sake of easily checking if they're null. You're solving one problem by creating a much bigger problem. – Daniel Mann Mar 21 '15 at 16:21
  • @DanielMann well what could you do else to make it shorter? i was just giving an example – JoJo Mar 21 '15 at 16:23

12 Answers12

69

With newer version of C# language you can write this without additional library or additional method call:

_ = someArg ?? throw new ArgumentNullException(nameof(someArg));
_ = otherArg ?? throw new ArgumentNullException(nameof(otherArg));

Starting from .NET6 you can also write this:

ArgumentNullException.ThrowIfNull(someArg);

Starting from .NET7 you can handle empty string and null checking:

ArgumentException.ThrowIfNullOrEmpty(someStringArg);
manuc66
  • 2,701
  • 29
  • 28
  • 12
    In case you haven't encountered [discards](https://learn.microsoft.com/en-us/dotnet/csharp/discards) yet and like me are wondering about the underscore. – Daniel Apr 03 '20 at 07:52
  • 2
    Newer shorter way with upcoming .NET6: `ArgumentNullException.ThrowIfNull(someArg);` (https://stackoverflow.com/a/69836300/2315856) – user2315856 Nov 04 '21 at 08:33
34
public static class Ensure
{
    /// <summary>
    /// Ensures that the specified argument is not null.
    /// </summary>
    /// <param name="argumentName">Name of the argument.</param>
    /// <param name="argument">The argument.</param>
    [DebuggerStepThrough]
    [ContractAnnotation("halt <= argument:null")]        
    public static void ArgumentNotNull(object argument, [InvokerParameterName] string argumentName)
    {
        if (argument == null)
        {
            throw new ArgumentNullException(argumentName);
        }
    }
}

usage:

// C# < 6
public Constructor([NotNull] object foo)
{
    Ensure.ArgumentNotNull(foo, "foo");
    ...
}

// C# >= 6
public Constructor([NotNull] object bar)
{
    Ensure.ArgumentNotNull(bar, nameof(bar));
    ...
}

The DebuggerStepThroughAttribute comes in quite handy so that in case of an exception while debugging (or when I attach the debugger after the exception occurred) I will not end up inside the ArgumentNotNull method but instead at the calling method where the null reference actually happened.

I am using ReSharper Contract Annotations.

  • The ContractAnnotationAttribute makes sure that I never misspell the argument ("foo") and also renames it automatically if I rename the foo symbol.
  • The NotNullAttribute helps ReSharper with code analysis. So if I do new Constructor(null) I will get a warning from ReSharper that this will lead to an exception.
  • If you do not like to annotate your code directly, you can also do the same thing with external XML-files that you could deploy with your library and that users can optionally reference in their ReSharper.
Pang
  • 9,564
  • 146
  • 81
  • 122
bitbonk
  • 48,890
  • 37
  • 186
  • 278
  • do you know about how to rewrite this code to [Code Contract](https://learn.microsoft.com/en-us/dotnet/framework/debug-trace-profile/code-contracts) instead ResharperAnnotation. Is it even possible? Or I didn't understand. In advance Thank you for any helps – Alexcei Shmakov Jun 03 '19 at 05:57
  • Code contracts are basically [dead](https://github.com/dotnet/corefx/issues/24681#issuecomment-337765314). I wouldn’t use them anymore. If you are on .NET Core or plan to switch to it, I would use the new [nullable reference types](https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references) feature. – bitbonk Jun 03 '19 at 08:38
  • At the LinksPlatform we have [Platform.Exceptions library](https://github.com/linksplatform/Exceptions) that contains a similar implementation of single line checkers methods. If you need additional checks, you can either extend our implementation with extension methods or ask us to add these checks into our library. – Konard Aug 10 '21 at 10:31
16

If you have too many parameters in your constructors, you'd better revise them, but that's another story.

To decrease boilerplate validation code many guys write Guard utility classes like this:

public static class Guard
{
    public static void ThrowIfNull(object argumentValue, string argumentName)
    {
        if (argumentValue == null)
        {
            throw new ArgumentNullException(argumentName);
        }
    }

    // other validation methods
}

(You can add other validation methods that might be necessary to that Guard class).

Thus it only takes one line of code to validate a parameter:

    private static void Foo(object obj)
    {
        Guard.ThrowIfNull(obj, "obj");
    }
serge.karalenka
  • 980
  • 1
  • 15
  • 29
  • 15
    Just a minor note, you could also use the `nameof` operator instead of hard coding the argument name, e.g. `Guard.ThrowIfNull(obj, nameof(obj))` – Daniel Smith Jul 11 '16 at 20:48
  • @DanielSmith any reason to not move the nameof(obj) to inside of the ThrowIfNull method and only have one argument while you're at it? – aufty Apr 08 '20 at 21:27
  • 1
    @aufty because `nameof(obj)` just returns "obj". What Daniel meant there was `nameof(howeverYourParameterIsNamed)`. In `ThrowIfNull`, you have to write `nameof(argumentValue)` (or however you choose to name the parameter), so you will always get `NullReferenceException`: argumentValue was null... not very enlightening. – Vector Sigma May 27 '20 at 23:53
7

Null references are one sort of troubles you have to guard against. But, they are not the only one. The problem is wider than that, and it boils down to this: Method accepts instances of a certain type, but it cannot handle all instances.

In other words, domain of the method is larger than the set of values it handles. Guard clauses are then used to assert that actual parameter does not fall into that "gray zone" of the method's domain which cannot be handled.

Now, we have null references, as a value which is typically outside the acceptable set of values. On the other hand, it often happens that some non-null elements of the set are also unacceptable (e.g. empty string).

In that case, it may turn out that the method signature is too broad, which then indicates a design problem. That may lead to a redesign, e.g. defining a subtype, typically a derived interface, which restricts domain of the method and makes some of the guard clauses disappear. You can find an example in this article: Why do We Need Guard Clauses?

Zoran Horvat
  • 10,924
  • 3
  • 31
  • 43
  • I agree with what you said here but I don't see how I can apply it to the stated problem in order disallow nulls at compile time because reference types in c# are always nullable. – Tim Abell Sep 24 '20 at 08:43
  • 1
    @TimAbell OP didn't ask for that; anyway C# 8 is now introducing nullable reference types, so that you can force the compiler report all suspicious accesses to references that may be null. Other possibility is to rely on optional objects, which are not supported by C# natively. – Zoran Horvat Sep 24 '20 at 14:35
7

With newer version of C# (C# 10, .NET6 will be released in a few days) you can even do: ArgumentNullException.ThrowIfNull(someArg);

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

bluish
  • 26,356
  • 27
  • 122
  • 180
user2315856
  • 162
  • 2
  • 9
6

Ardalis has an excellent GuardClauses library.

It's nice to use Guard.Against.Null(message, nameof(message));

AlignedDev
  • 8,102
  • 9
  • 56
  • 91
5

In C# 8.0 and later, new helps are available. C# 8.0 introduces non-nullable reference types (a feature somewhat confusingly called "nullable reference types" in the docs). Prior to C# 8.0, all reference types could be set to null. But now with C# 8.0 and the 'nullable' project setting, we can say that reference types are by default non-nullable, and then make our variables and parameters nullable on a case-by-case basis.

So whereas at the moment, we recognize code like this:

public void MyFunction(int thisCannotBeNull, int? thisCouldBeNull)
{
    // no need for checking my thisCannotBeNull parameter for null here
}

If you set <Nullable>enable</Nullable> for your C# v8.0+ project, you can do things like this too:

public void MyFunction(MyClass thisCannotBeNull, MyClass? thisCouldBeNull)
{
    // static code analysis at compile time checks to see if thisCannotBeNull could be null
}

The null-checking is done at compile-time, using static code analysis. So if you've coded it in a way that means a null could turn up there, you'll get a compiler warning (which you can upgrade to an error if you want). So lots (but not all) of the situations where you need a run-time check for null parameters can be handled as a compile-time check based on your code.

Jinlye
  • 1,774
  • 18
  • 19
5

The !! operator (not actually part of C#, but interesting story)

Microsoft attempted to introduce a new language feature that was known as parameter null checking or also as the bang bang operator in C# 10 and later again in C# 11, but decided to not release it.

It would have been the shortest way to do this (by far): only 2 exclamation marks !! right after the argument(s) you want to check for null.

Before:

public void test(string someArg){
    if (someArg == null)
    {
        throw new ArgumentNullException(nameof(someArg));
    }
    // other code
}

With that new operator:

public void test(string someArg!!){
    // other code
}

Calling test(null) would have lead to an ArgumentNullException telling you that someArg is null.

Microsoft mentioned it in early 2021, but it did not become part of C# 10: A video on the 'Microsoft Developer' YouTube channel explaining the new feature.

The feature was implemented in February 2022 for C#11, see on GitHub.

It was removed later see on Microsoft dev blog because of lots of criticism with the argument, that the bang bang operator is very shouty.

The developers of the C# language think, that there is a majority for such a feature, but that it's not as large as usual and that it's possible, that this features comes with a later C# version.


hardfork
  • 2,470
  • 1
  • 23
  • 43
3

You might try my Heleonix.Guard library, which provides guard functionality.

You can write guard clauses like below:

// C# 7.2+: Non-Trailing named arguments
Throw.ArgumentNullException(when: param.IsNull(), nameof(param));

// OR

// Prior to C# 7.2: You can use a helper method 'When'
Throw.ArgumentNullException(When(param.IsNull()), nameof(param));

// OR
Throw.ArgumentNullException(param == null, nameof(param));

// OR
Throw.ArgumentNullException(When (param == null), nameof(param));

It provides throwing of many existing exceptions, and you can write custom extension methods for custom exceptions. Also, the library refers to the 'Heleonix.Extensions' library with predicative extensions like IsNull, IsNullOrEmptyOrWhitespace, IsLessThan and many more to check your arguments or variables against desired values. Unlike some other guard libraries with fluent interfaces, these extensions do not generate intermediate objects, and since implementation is really straightforward, they are performant.

Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
Hennadii
  • 149
  • 1
  • 6
  • Am I right in thinking that all arguments are evaluated, even when the condition is false? That's not a problem for the simple cases in the question, but something users would want to be aware of when using this library in other contexts. – Toby Speight Jun 19 '18 at 14:30
  • Each argument should have separate check. I.e. for the case in the question it would be as below: `Throw.ArgumentNullException(when: someArg.IsNull(), nameof(someArg)); Throw.ArgumentNullException(when: otherArg.IsNull(), nameof(otherArg));` If evaluation of the first expression `someArg.IsNull()` is `true`, then the exception is thrown, so the second expression `otherArg.IsNull()` is not evaluated etc. – Hennadii Jun 19 '18 at 23:15
  • What I mean is than `nameof(someArg)` is always evaluated, even if `someArg.IsNull()` returns false, unlike the if/then construct. In this case, that's probably okay, but may be undesirable if instead of a simple `nameof()` we had something with side effects (including timing effects). – Toby Speight Jun 20 '18 at 07:38
  • Right. That's why throwing of exceptions should be like a simple single-line expression. If there is some i.e. multi-line logic, especially with side effects, it is better to use regular `if` statement because that logic would be more readable (as for me, i'd consider it as part of your agorithm) – Hennadii Jun 20 '18 at 10:46
2

The simplest approach I've found is inspired by Dapper's use of anonymous types. I've written a Guard class that uses anonymous types to get name of properties. The guard itself is the following

    public class Guard
    {
        public static void ThrowIfNull(object param) 
        {
            var props = param.GetType().GetProperties();
            foreach (var prop in props) 
            {
                var name = prop.Name;
                var val = prop.GetValue(param, null);

                _ = val ?? throw new ArgumentNullException(name);
            }
        }
    }

You then use it like so

...
        public void Method(string someValue, string otherValue)
        {
            Guard.ThrowIfNull(new { someValue, otherValue }); 
        }
...

When the ArgumentNullException is thrown, reflection is used to determine the name of the property which will then be displayed in your exception

Bjarke Sporring
  • 528
  • 5
  • 7
2

If you want to save typing the argument name twice, like Guard.AgainstNull(arg, nameof(arg));

check out YAGuard, where you can write Guard.AgainstNull(arg);

No need to specify the name of the argument in the guard clause, but in the argument thrown, the name is correctly resolved.

It also supports guard-and-set in the form MyProperty = Assign.IfNotNull(arg);

Nuget: YAGuard

Disclaimer: I'm the author of YAGuard.

balintn
  • 988
  • 1
  • 9
  • 19
1

There is a nuget package called SwissKnife. Install SwissKnife from nuget gallery. It provides you with many options starting with null checking for arguments Argument.IsNotNullOrEmpty(args,"args") under SwissKnife.Diagnostics.Contracts namespace alongwith with option idoim and many more. You can set Option<Class_Name> _someVar and then check if _someVar.IsSome or _someVar.IsNone. This helps against nullable classes as well. Hope this helps.

Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77