Why do we get possible dereference null reference warning, when null reference does not seem to be possible?

This is effectively a duplicate of the answer that @stuartd linked, so I’m not going to go into super deep details here. But the root of the matter is that this is neither a language bug nor a compiler bug, but it’s intended behavior exactly as implemented. We track the null state of a variable. When you initially declare the variable, that state is NotNull because you explicitly initialize it with a value that is not null. But we don’t track where that NotNull came from. This, for example, is effectively equivalent code:

#nullable enable
class Program
{
    static void Main()
    {
        M("");
    }
    static void M(string s)
    {
        var b = s == null;
        var i = s.Length; // warning CS8602: Dereference of a possibly null reference
    }
}

In both cases, you explicitly test s for null. We take this as input to the flow analysis, just as Mads answered in this question: https://stackoverflow.com/a/59328672/2672518. In that answer, the result is that you get a warning on the return. In this case, the answer is that you get a warning that you dereferenced a possibly null reference.

It does not become nullable, simply because we were silly enough to compare it with null.

Yep, it actually does. To the compiler. As humans, we can look at this code and obviously understand that it cannot throw a null reference exception. But the way the nullable flow analysis is implemented in the compiler, it cannot. We did discuss some amount of improvements to this analysis where we add additional states based on where the value came from, but we decided that this added a great deal of complexity to the implementation for not a great deal of gain, because the only places where this would be useful is for cases like this, where the user initializes a variable with a new or a constant value and then checks it for null anyway.

Leave a Comment