2
votes

I was playing around with VS2019, tyring new C#-8 features on an existing code body. I took a small project and proceeded to convert it to use the new nullable reference types feature. In the process, I came across this case:

using System;

#nullable enable

namespace NullableRefTest
{
  class Demo
  {
    public string? Property { get; set; }

    public int Test()
    {
      if (null == Property) // 1
        throw new InvalidOperationException();

      int f()
      {
        return Property.Length; // 2
      }

      return f(); 
    }
  }
}

Compiling this with C#-8 enabled generates a CS8602 possible dereference of a null refrence warning on // 2.

Now, I would maintain, that there is clearly no null reference possible here - the visibility and lifetime of f() is such that it cannot possibly be invoked before the null reference test at //1.

I'm assuming that the warning arises because of how local functions are actually implemented by hoisting them to an anonymous class, and within that class considered out of context, this is indeed a possible null reference.

Is this just a case that the compiler isn't getting right yet, or is there something more insidious here that says that this warning should remain?

1
I'm assuming in this case, the compiler just doesn't recognize your null check in the parent scope. They may introduce a smarter check for it in the future.Devon
If you insert Property == null just before the call to f. This will throwAvin Kavish

1 Answers

2
votes

When you are confident the variable cannot be null, you can use ! (null-forgiving operator) to override the compiler behavior.

  int f()
  {
    return Property!.Length; // 2
  }