5
votes

In C# 8.0, suppose I have nullable references enabled with <Nullable>enable</Nullable> in the .csproj. This gives me warnings when I try to use possibly-null references in a non-nonnullable usage, so that's great. I can then turn on <WarningsAsErrors /> and get this strictly enforced as errors rather than warnings.

So I was hopeful with this language construct that I could avoid certain null-checking code. Specifically, I (and many others) often wrote methods like this:

public string Message { get; set; }
public void SetFoo(string message) {
   Message = message ?? throw new ArgumentNullException(nameof(message)); 
   Console.WriteLine(Message.ToUpper())
}

I was hopeful to drop the null check, since the reference is non-nullable, and instead write

public string Message { get; set; }
public void SetFoo(string message) {
   Message = message; 
   Console.WriteLine(Message.ToUpper())
}

This seems to be good, in that a call like myThing.SetFoo(null); generates a compiler warning/error. However, I find that code such as myThing.SetFoo(null!); compiles and runs anyway! So, in order to code defensively, I need to keep the old guard clause anyway in case someone calls it with such misuse of the ! operator, right?

Is there any way to avoid writing code to check for null on non-nullable references? I'd expect that there could be a way to make the compiler infer that it should throw an exception in such cases rather than just ignoring non-nullability, but I don't see it.

1
As you noted, NRTs are compile-time only. The general opinion is that you can elide null-checks on internal interfaces (so long as all your code enables NRTs), but you should keep them on external interfaces - canton7
It's a public method (presumably on a public type), so it can be called from a project without nullable reference types, where that can pass null. - CodeCaster
There is also MaybeNull/AllowNull attributes, which allow to return a set a possible null value to non-nullable reference. You should keep in mind them as well, in addition to null-forgiving operator - Pavel Anikhouski

1 Answers

5
votes

Can we avoid null reference guard clauses with non-nullable method parameters in C# 8.0?

No, because:

  • You can pass nulls explicitly, using null!, which has its usages, see also this question.
  • External code that is compiled without nullable reference type support can call your code and pass null, without getting warnings or errors in the calling project.