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;
}
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;
}
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
There are more awesome attributes
Check Microsoft docs