I've found some behaviour with the nullability analysis in a C# project that I don't understand, and I was hoping someone might be able to shed some light on it.
In short, I've got a nullability warning which I can't work out why it's appearing and, more confusingly, it disappears when I comment out some code that doesn't look like it should affect the nullability analysis.
It's probably just easier to show the code than try to describe it in more detail - an MRE is as follows...
ConsoleApp1.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
Program.cs
static object? GetTask()
{
return new object();
}
static void DoSomething()
{
var plans = Enumerable.Empty<Plan>();
var filtered = plans
.Select(
plan => new
{
Value = plan.Schedule
}
);
var tasks = filtered.Select(
anon => GetTask()
);
}
DoSomething();
class Plan
{
public object? Schedule
{
get;
set;
}
}
The code as-is gives a nullability warning:
CS8619 Nullability of reference types in value of type '<anonymous type: object Value>' doesn't match target type '<anonymous type: object? Value>'.
but if I comment out the var tasks = ...
statement the nullability warning disappears...
It looks like the analyser is getting its knickers in a twist because it decides that the Value
property of the anonymous type should be "not null" (i.e. <anonymous type: object Value>
) but then proceeds to create an anonymous object with a nullable Value
(i.e. <anonymous type: object? Value>
.
It also seems to be related to the GetTasks
method - if you replace anon => GetTask()
with anon => null as object
the nullability warning goes away as well:
I'm half-imagining this might be a bug in the nullability analyser, but is there a rational explanation that I just can't see?
For reference, versions are:
Microsoft Visual Studio Professional 2022 (64-bit) - Preview
Version 17.3.0 Preview 1.1
and
C:>dotnet --list-sdks
3.1.419 [C:\Program Files\dotnet\sdk]
5.0.200 [C:\Program Files\dotnet\sdk]
5.0.214 [C:\Program Files\dotnet\sdk]
6.0.203 [C:\Program Files\dotnet\sdk]
6.0.300 [C:\Program Files\dotnet\sdk]
7.0.100-preview.4.22252.9 [C:\Program Files\dotnet\sdk]
Update
Moving the code out of the DoSomething
method also seems to remove the warning: