Roslyn: CS8604 False-negative in .Net Standard project vs .Net Core

Created on 11 Aug 2020  路  8Comments  路  Source: dotnet/roslyn

Describe the bug

In a .Net Standard project, trying to use a Stream? instead of a Stream raises a CS8604 warning. But not when using a Stream? to initialize a StreamReader.
In a .Net Standard project, both situations raise a CS8604 warning.

Steps To Reproduce

Here is the short class that I am using, with <Nullable>enable</Nullable> in .NetStandard 2.1 project and .NetCoreApp 3.1 project.

public class Test
{
    public async Task<Stream?> GetFile(string file)
    {
        Stream? stream = null;

        if (File.Exists(file))
        {
            stream = File.OpenRead(file);
        }

        return await Task.FromResult(stream);
    }

    public async Task TestStreamReader(string file)
    {
        using(Stream stream = await GetFile(file))
        {
            // Do stuff...
        }

        using(StreamReader reader = new StreamReader(await GetFile(file)))
        {
            // Do stuff...
        }
    }
}

Expected behavior

CS8604 for both using Stream and StreamReader in .Net Standard and .Net Core

Actual behavior

CS8604 for Stream in .Net Standard and for Stream and StreamReader in .Net Core

Analyzer

Package: Microsoft.CodeAnalysis.FxCopAnalyzers

Version: v3.3.0 (Latest)

Diagnostic ID: CA1716

Additional context

I understand this might be "intentional" as it should only work properly in .Net Core App if I understand this correctly but I feel like the fact that this is "half" working in .Net Standard can make it confusing.

Area-Compilers Need More Info New Language Feature - Nullable Reference Types

All 8 comments

Could you please clarify the issue by adding comments indicating where warnings are given and in which target frameworks each warning is given?

Could you please clarify the issue by adding comments indicating where warnings are given and in which target frameworks each warning is given?

Yes.

For this code

using(Stream stream = await GetFile(file))
{
    // Do stuff...
}

In both target frameworks, the await GetFile(file) part is underlined with green squiggles with error CS8600 C# Converting null literal or possible null value to non-nullable type. which makes sense.

And for this code

using(StreamReader reader = new StreamReader(await GetFile(file)))
{
    // Do stuff...
}
  • For target framework netstandard2.1 nothing happens
  • For target framework netcoreapp3.1, the await GetFile(file) part is underlined with green squiggles with error CS8604 C# Possible null reference argument for parameter 'stream' in.

Thanks for clarifying. This behavior is "By Design" due to the lack of library annotations.

The issue here is that the library containing StreamReader does not have any nullable annotations in netstandard2.1. This means the language treats the parameters as oblivious which allows for null values. Once you switch to netcoreapp3.1 the annotations come into play and the warning appears.

Sounds good, thanks for the explanation.

Am I correct to assume that with net5.0 on its way those annotations will not find their way to netstandard2.1 ?

Correct, there are no plans that I am aware of to introduce nullability annotations to netstandard2.1.

Thank you!

Am I correct to assume that with net5.0 on its way those annotations will not find their way to netstandard2.1 ?

Yes, but there is also a project that lets you copy annotations from one target framework to another.

Thanks @svick I will check this out!

Was this page helpful?
0 / 5 - 0 ratings