Benefits of C# 8.0 nullable reference types when working with external libraries

Viewed 365

I'm currently in the process of updating an ASP.NET Core 2.1 project to .NET 5 and at the same time trying to take advantage of some of the newer C# language features such as: C# 8.0's nullable reference types

I tried enabling it for one of my projects and started going through some of the warnings popping up. At one place I'm zipping a folder where I have some debug logging:

var dirInfo = _fs.DirectoryInfo.FromDirectoryName(absPath);
var subEntries = dirInfo.GetFileSystemInfos();
foreach (var info in subEntries)
{
    var isDirInfo = IsDirectory(info.Attributes);
    _logger.Debug("Adding item to archive with parameters: type={type}, name={name}, bytes={size}",
        isDirInfo ? "directory" : "file",
        info.Name,
        isDirInfo ? 0 : (info as FileInfoBase).Length);
    //                   ~~~~~~~~~~~~~~~~~~~~
    // CS8602: Dereference of a possibly null reference.

    AddToZip(archive, info.FullName, Path.Join(entryPath, info.Name), isDirInfo);
}

In the above snippet _fs is an IFileSystem from the System.IO.Abstractions library. The exact warning above has nothing to do with the actual question here but my investigation into how to properly fix it made me wonder why a warning is not shown at the second line of the snippet. There's nothing in the FromDirectoryName signature that says it cannot be null, since the library is not using this feature yet. So, I'd expect the compiler to assume dirInfo may be null and show a warning when trying to dereference it at the second line. (Let's for a moment pretend that FromDirectoryName would return null rather than throw an exception if absPath does not exist - it's my best real world example at the moment)

As far as I've been able to find out around the internet this is expected. In other words: because the return type of FromDirectoryName is IDirectoryInfo and not IDirectoryInfo? the compiler behaves as if dirInfo will never be null. Whether this is a design choice or technical limitation I don't know, but it made me wonder what the benefits of this new nullable reference type are. To me it seems like not being able to rely on the compiler to warn you about your use of values returned from external libraries defeats quite a big part of this "new" feature because it may lead you to overlook potential null-reference exceptions.

Am I either interpreting the compiler's behavior in above code snippet incorrectly or am I just having the wrong approach to using nullable reference types in a project that depends on several external libraries? I hope you can help enlightening me a bit on how to approach the use of this language feature in such situations.


Edit (13-01-2021):

In a blog post from Microsoft they even point out that you cannot trust the compiler to interpret method signatures from libraries that haven't enabled the feature yet. It strengthens my theory that unless you are working on a project with very few 3rd party libraries, you are likely to waste your time implementing this feature and still not get null-safe code.

Edit (14-01-2021):

Added a reproducible example: https://github.com/Xerillio/csharp8-nrt-test

0 Answers
Related