Search code examples
c#nullablec#-8.0nullable-reference-types

C# 8 validate arguments with utility method


Say I have a method that accepts a nullable reference type like:

int Func(string? param)
{
    return param.Length;
}

The compiler correctly warns that param should be checked for null.

Before C# 8, I was used to validating arguments with external utility functions like this:

public static class Validate
{
   public static void NotNull(object? value, string parameterName, string? field = null)
   {
     if (value == null) throw new ArgumentNullException(parameterName + (field == null ? string.Empty : "." + field));
   }
}
… 
int Func(string? param)
{
    Validate.NotNull(param, nameof(param));
    return param.Length;
}

In this case, it seems that the compiler can't detect that argument param is actually checked for null inside of the Validate method, and thus still complains.

Is there no other way to directly test for null values inside of the method?

int Func(string? param)
{
    if (value == null) throw new ArgumentNullException(nameof(param));
    return param.Length;
}

Solution

  • You could use [NotNull] for this, so the compiler learns that after calling Validate.NotNull the value is never null.

    using System.Diagnostics.CodeAnalysis;
    
    public static class Validate
    {
       public static void NotNull([NotNull]object? value, string parameterName, string? field = null)
       {
         if (value == null) throw new ArgumentNullException(parameterName + (field == null ? string.Empty : "." + field));
       }
    }
    

    Result: this won't give warnings anymore:

    int Func(string? param)
    {
        Validate.NotNull(param, nameof(param));
        return param.Length;
    }
    

    Side note - signature of Func method

    Of course the question is why the Func method doesn't have the signature:

    int Func(string param) // no null allowed
    

    If that isn't possible, you could also use another attribute [DisallowNull], so

    int Func([DisallowNull] string? param) // gives warning if called with null compile time
    

    Side note - more attributes

    There are more awesome attributes

    enter image description here

    Check Microsoft docs